162 votes

Comment copier une liste java.util.List dans une autre liste java.util.List ?

J'ai un List<SomeBean> qui est alimenté à partir d'un service Web. Je veux copier/cloner le contenu de cette liste dans une liste vide du même type. Une recherche sur Google pour copier une liste m'a suggéré d'utiliser Collections.copy() méthode. Dans tous les exemples que j'ai vus, la liste de destination était censée contenir le nombre exact d'éléments pour que la copie ait lieu.

Comme la liste que j'utilise est alimentée par un service web et qu'elle contient des centaines d'objets, je ne peux pas utiliser la technique ci-dessus. Ou bien je l'utilise mal ??! Quoi qu'il en soit, pour que cela fonctionne, j'ai essayé de faire quelque chose comme ceci, mais j'ai toujours un message d'erreur IndexOutOfBoundsException .

List<SomeBean> wsList = app.allInOne(template);

List<SomeBean> wsListCopy=new ArrayList<SomeBean>(wsList.size());   
Collections.copy(wsListCopy,wsList);
System.out.println(wsListCopy.size());

J'ai essayé d'utiliser le wsListCopy=wsList.subList(0, wsList.size()) mais j'ai obtenu un ConcurrentAccessException plus tard dans le code. Un coup d'essai :)

Quoi qu'il en soit, ma question est simple, comment puis-je copier l'intégralité du contenu de ma liste dans une autre liste ? Pas par itération, bien sûr.

5voto

Nicolas Henneaux Points 4987

Il existe une autre méthode avec Java 8 de manière non sécurisée.

List<SomeBean> wsListCopy = Optional.ofNullable(wsList)
    .map(Collection::stream)
    .orElseGet(Stream::empty)
    .collect(Collectors.toList());

Si vous voulez sauter un élément.

List<SomeBean> wsListCopy = Optional.ofNullable(wsList)
    .map(Collection::stream)
    .orElseGet(Stream::empty)
    .skip(1)
    .collect(Collectors.toList());

Avec Java 9+, la méthode stream de Optional peut être utilisée

Optional.ofNullable(wsList)
    .stream()
    .flatMap(Collection::stream)
    .collect(Collectors.toList())

2voto

Abhay Yadav Points 78

J'ai essayé quelque chose de similaire et j'ai pu reproduire le problème (IndexOutOfBoundsException). Voici mes conclusions :

1) L'implémentation de la méthode Collections.copy(destList, sourceList) vérifie d'abord la taille de la liste de destination en appelant la méthode size(). Étant donné que l'appel à la méthode size() renvoie toujours le nombre d'éléments de la liste (0 dans ce cas), le constructeur ArrayList(capacity) garantit uniquement la capacité initiale du tableau de sauvegarde et cela n'a aucun rapport avec la taille de la liste. Par conséquent, nous obtenons toujours une IndexOutOfBoundsException.

2) Une façon relativement simple est d'utiliser le constructeur qui prend une collection comme argument :

List<SomeBean> wsListCopy=new ArrayList<SomeBean>(wsList);

1voto

T04435 Points 361

J'avais le même problème ConcurrentAccessException et ma solution était de :

List<SomeBean> tempList = new ArrayList<>();

for (CartItem item : prodList) {
  tempList.add(item);
}
prodList.clear();
prodList = new ArrayList<>(tempList);

Ainsi, il ne fonctionne qu'une seule opération à la fois et évite l'Exeption...

1voto

Vous pouvez utiliser addAll().

eg : wsListCopy.addAll(wsList);

0voto

Jon Nelson Points 101

Re : indexOutOfBoundsException Si la liste est de taille 1, les arguments de votre sous-liste sont le problème ; vous devez terminer la sous-liste à la taille 1. Etant basé sur zéro, le dernier élément d'une liste est toujours de taille 1, il n'y a pas d'élément dans la position de taille, d'où l'erreur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X