Copier une liste dans une autre liste en Java

1. Vue d'ensemble

Dans ce rapide didacticiel, nous montrerons différentes manières de copier une liste dans une autre liste et une erreur courante produite dans le processus.

Pour une introduction à l'utilisation des collections , veuillez consulter cet article ici.

2. Constructeur

Un moyen simple de copier une liste consiste à utiliser le constructeur qui prend une collection comme argument:

List copy = new ArrayList(list);

En raison du fait que nous copions la référence ici et que nous ne clonons pas les objets, toutes les modifications apportées à un élément affecteront les deux listes.

Pour cette raison, l'utilisation du constructeur est bonne pour copier des objets immuables:

List copy = new ArrayList(list);

Integer est une classe immuable, sa valeur est définie lors de la création de l'instance et ne peut jamais changer.

Une référence Integer peut donc être partagée par plusieurs listes et threads et personne ne peut changer sa valeur.

3. Lister ConcurrentAccessException

Un problème courant lors de l'utilisation des listes est l' exception ConcurrentAccessException . Cela pourrait signifier que nous modifions la liste pendant que nous essayons de la copier, très probablement dans un autre thread.

Pour résoudre ce problème, nous devons soit:

  • Utilisez une collection conçue pour l'accès simultané
  • Verrouillez la collection de manière appropriée pour la parcourir
  • Trouvez un moyen d'éviter d'avoir à copier la collection originale

Compte tenu de notre dernière approche, ce n'est pas thread-safe. Ainsi, si nous voulons résoudre notre problème avec la première option, nous souhaitons peut-être utiliser CopyOnWriteArrayList , dans lequel toutes les opérations mutatives sont implémentées en faisant une nouvelle copie du tableau sous-jacent.

Pour plus d'informations, reportez-vous à cet article.

Si nous voulons verrouiller la collection , il est possible d'utiliser une primitive de verrouillage pour sérialiser l'accès en lecture / écriture, telle que ReentrantReadWriteLock .

4. AddAll

Une autre approche pour copier des éléments consiste à utiliser la méthode addAll :

List copy = new ArrayList(); copy.addAll(list);

Il est important de garder à l'esprit chaque fois que vous utilisez cette méthode, que, comme avec le constructeur, le contenu des deux listes référencera les mêmes objets.

5. Collections.copie

La classe Collections se compose exclusivement de méthodes statiques qui opèrent sur ou retournent des collections.

L'un d'eux est la copie , qui nécessite une liste de sources et une liste de destinations au moins aussi longues que la source.

Il conservera l'index de chaque élément copié dans la liste de destination comme l'original:

List source = Arrays.asList(1,2,3); List dest = Arrays.asList(4,5,6); Collections.copy(dest, source);

Dans l'exemple ci-dessus, tous les éléments précédents de la liste dest ont été écrasés car les deux listes ont la même taille.

Dans le cas où la taille de la liste de destination est plus grande que la source:

List source = Arrays.asList(1, 2, 3); List dest = Arrays.asList(5, 6, 7, 8, 9, 10); Collections.copy(dest, source);

Seuls les trois premiers éléments ont été écrasés tandis que le reste des éléments de la liste est conservé.

6. Utilisation de Java 8

Cette version de Java ouvre nos possibilités en ajoutant de nouveaux outils. Celui que nous explorerons dans les exemples suivants est Stream :

List copy = list.stream() .collect(Collectors.toList());

Les principaux avantages de cette méthode sont la possibilité d'utiliser des sauts et des filtres. Dans l'exemple suivant, nous allons ignorer le premier élément:

List copy = list.stream() .skip(1) .collect(Collectors.toList());

Il est également possible de filtrer par la longueur de la chaîne ou en comparant un attribut de nos objets:

List copy = list.stream() .filter(s -> s.length() > 10) .collect(Collectors.toList());
List flowers = list.stream() .filter(f -> f.getPetals() > 6) .collect(Collectors.toList());

Il est probable que nous souhaitons travailler de manière null-safe:

List flowers = Optional.ofNullable(list) .map(List::stream)   .orElseGet(Stream::empty)   .collect(Collectors.toList());

Et ignorez un élément en utilisant également cette méthode:

List flowers = Optional.ofNullable(list)   .map(List::stream).orElseGet(Stream::empty)   .skip(1)   .collect(Collectors.toList());

7. Utilisation de Java 10

Enfin, l'une des dernières versions de Java nous permet de créer une liste immuable contenant les éléments de la collection donnée :

List copy = List.copyOf(list);
Les seules conditions sont que la Collection donnée ne doit pas être nulle et ne doit contenir aucun élément nul.

8. Conclusion

Dans cet article, nous avons exploré différentes manières de copier une liste dans une autre liste avec différentes versions de Java et une erreur courante produite dans le processus. Comme toujours, des exemples de code peuvent être trouvés sur GitHub ici et ici.