Combinaison de différents types de collections en Java

Combinaison de différents types de collections en Java

1. introduction

Dans ce rapide didacticiel, nous allons explorer différentes manières de combiner des collections en Java.

Nous explorerons différentes approches utilisant Java et des frameworks externes tels que Guava, Apache, etc. Pour l'introduction aux collections, jetez un œil àat this series here.

2. Bibliothèques externes pour travailler avec des collections

Outre les approches natives, nous utiliserons également des bibliothèques externes. Veuillez ajouter les dépendances suivantes dans lespom.xml:


    org.apache.commons
    commons-collections4
    4.2


    org.apache.commons
    commons-exec
    1.3


    com.google.guava
    guava
    26.0-jre

Les dernières versions sont disponibles sur Maven Central pourCommons,Commons-exec etGuava.

3. Combinaison de tableaux en Java

3.1. Solution Java native

Java est livré avec une méthodevoid arraycopy() intégrée qui copie un tableau source donné vers celui de destination.

Nous pouvons l'utiliser de la manière suivante:

Object[] combined = new Object[first.length + second.length];
System.arraycopy(first, 0, combined, 0, first.length);
System.arraycopy(second, 0, combined, first.length, second.length);

Dans cette méthode, avec les objets de tableau, nous spécifions également la position à partir de laquelle nous devons copier, et nous passons également le paramètre length.

Il s'agit d'une solution Java native, elle ne nécessite donc aucune bibliothèque externe.

3.2. Utilisation de l'API Java 8Stream

Les flux constituent un moyen efficace d'itérer plusieurs types de collections. Pour commencer avec les flux, rendez-vous sur lesJava 8 Stream API Tutorial.

Pour combiner des tableaux en utilisant unStream, nous pouvons utiliser ce code:

Object[] combined = Stream.concat(Arrays.stream(first), Arrays.stream(second)).toArray();

Stream.concat() crée un flux concaténé dans lequel les éléments du premier flux sont suivis par les éléments du deuxième flux, qui est ensuite converti en un tableau à l'aide detoArray() method.

Le processus de création du flux est le même pour différents types de collections. Cependant, nous pouvons le collecter de différentes manières pour en extraire différentes structures de données.

Nous reviendrons sur cette méthode dans les sections 4.2. et 5.2. pour voir comment nous pouvons utiliser la même méthode surLists etSets.

3.3. Utilisation deArrayUtils d'Apache Commons

La bibliothèque Apache commons nous fournit la méthodeaddAll() du packageArrayUtils. Nous pouvons fournir la destination et le tableau source en tant que paramètres, et cette méthode renverra un tableau combiné:

Object[] combined = ArrayUtils.addAll(first, second);

Cette méthode est également abordée en détail dans l'article deArray Processing with Apache Commons Lang 3.

3.4. Utilisation de goyave

Guava nous fournit la méthodeconcat() dans le même but:

Object [] combined = ObjectArrays.concat(first, second, Object.class);

Il peut être utilisé avec différents types de données et accepte deux tableaux source ainsi que le littéral de classe pour renvoyer le tableau combiné.

4. Combinaison deList en Java

4.1. Utilisation de la méthodeCollection nativeaddAll()

L'interfaceCollection elle-même nous fournit la méthodeaddAll(), qui ajoute tous les éléments de la collection spécifiée à l'objet appelant. Ceci est également discuté en détail dansthis example article:

List combined = new ArrayList<>();
combined.addAll(first);
combined.addAll(second);


Étant donné que cette méthode est fournie dans l'interface la plus parente du framework Collections, c'est-à-dire l'interfaceCollection, elle peut être appliquée à tous lesLists etSets.

4.2. Utiliser Java 8

Nous pouvons utiliserStream etCollectors de la manière suivante pour combinerLists:

List combined = Stream.concat(first.stream(), second.stream()).collect(Collectors.toList());


C'est la même chose que ce que nous avons fait dans le cas deArrays dans la section 3.2, mais au lieu de le convertir en tableau, nous avons utilisé des collecteurs pour le convertir en liste. Pour en savoir plus sur lesCollectors, visitezGuide to Java 8’s Collectors.

Nous pouvons également utiliserflatMaps de cette manière:

List combined = Stream.of(first, second).flatMap(Collection::stream).collect(Collectors.toList());


First, we’re using Stream.of() which returns a sequential stream of two lists –  first and second. We’ll then pass it to flatMap which will return the contents of a mapped stream after applying the mapping function. Cette méthode est également abordée dans l'article deMerging Streams in Java.

Pour en savoir plus sur lesflatMap, rendez-vous surthis example article.

4.3. Utilisation deListUtils d'Apache Commons

CollectionUtils.union  effectue l'union de deux collections et renvoie une collection qui contient tous les éléments:

List combined = ListUtils.union(first, second);


Cette méthode est également discutée dansA Guide to Apache Commons Collections CollectionUtils. Pour plus d'informations, reportez-vous à la section 4.9. de cet article.

4.4. Utilisation de goyave

To merge a List using Guava, we’ll use Iterable which consists of the concat() method. Après avoir concaténé toutes les collections, nous pouvons rapidement obtenir l'objetList combiné comme indiqué dans cet exemple:

Iterable combinedIterables = Iterables
  .unmodifiableIterable(Iterables.concat(first, second));
List combined = Lists.newArrayList(combinedIterables);





5. Combinaison deSet en Java

5.1. Solution Java simple

Comme nous l'avons déjà discuté dans la section 4.1., L'interfaceCollection est livrée avec une méthodeaddAll() intégrée qui peut également être utilisée pour copierLists etSets:

Set combined = new HashSet<>();
combined.addAll(first);
combined.addAll(second);



5.2. Utilisation des flux Java 8

La même fonction que nous avons utilisée pour les sobjectsList peut être appliquée ici:

Set combined = Stream
  .concat(first.stream(), second.stream())
  .collect(Collectors.toSet());


La seule différence notable ici en comparant à list est qu'au lieu d'utiliserCollectors.toList(), nous utilisonsCollectors.toSet() pour accumuler tous les éléments des deux flux fournis dans un nouveauSet.

Et similaire àLists, lorsque vous utilisezflatMaps onSets, cela ressemblerait à:

Set combined = Stream.of(first, second)
  .flatMap(Collection::stream)
  .collect(Collectors.toSet());



5.3. Utiliser Apache Commons

Comme pour lesListUtils, nous pouvons également travailler avec lesSetUtils qui font une union des élémentsSet:

Set combined = SetUtils.union(first, second);



5.4. Utilisation de Guava

La bibliothèque Guava nous fournit une méthode simpleSets.union() pour combinerSets en Java:

Set combined = Sets.union(first, second);





6. Combinaison deMap en Java

6.1. Solution Java simple

Nous pouvons utiliser l'interfaceMap qui elle-même nous fournit la méthodeputAll() qui copie tous les mappages de l'argument fourni de l'objetMap vers l'objet de l'appelantMap :

Map combined = new HashMap<>();
combined.putAll(first);
combined.putAll(second);

6.2. Utiliser Java 8

Since Java 8, the Map class consists of merge() method which accepts a key, value, and a BiFunction. Nous pouvons l'utiliser avec une instruction Java 8forEach pour obtenir la fonctionnalité de fusion:

second.forEach((key, value) -> first.merge(key, value, String::concat));

Le troisième paramètre, à savoir la fonction de remappage, est utile lorsque la même paire clé-valeur est présente dans les deux mappes sources. Cette fonction spécifie ce qui doit être fait avec ces types de valeurs.

Nous pouvons également utiliserflatMap comme ceci:

Map combined = Stream.of(first, second)
  .map(Map::entrySet)
  .flatMap(Collection::stream)
  .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, String::concat));

6.3. Utilisation d'Apache Commons Exec

Map combined = MapUtils.merge(first, second);

6.4. Utiliser Google Guava

Nous pouvons utiliserImmutableMap fourni par la bibliothèque Guava de Google. La méthodeputAll() associe toutes les clés et valeurs de la carte donnée dans la carte créée:

Map combined = ImmutableMap.builder()
  .putAll(first)
  .putAll(second)
  .build();

7. Conclusion

Dans cet article, nous avons examiné différentes approches pour combiner différents types deCollections. Nous avons fusionné lesarrays,Lists,Sets etMaps.

Comme toujours, les extraits de code complets avec leurs tests unitaires appropriés peuvent être trouvésover on GitHub.