Définir des opérations en Java

1. Introduction

Un ensemble est un moyen pratique de représenter une collection unique d'objets.

Dans ce didacticiel, nous en apprendrons davantage sur ce que cela signifie et comment nous pouvons en utiliser un en Java.

2. Un peu de théorie des ensembles

2.1. Qu'est-ce qu'un ensemble?

Un ensemble est simplement un groupe d'objets uniques. Ainsi, une caractéristique importante de tout ensemble est qu'il ne contient pas de doublons .

Nous pouvons mettre tout ce que nous voulons dans un ensemble. Cependant, nous utilisons généralement des ensembles pour regrouper des éléments qui ont un trait commun. Par exemple, nous pourrions avoir un ensemble de véhicules ou un ensemble d'animaux.

Utilisons deux ensembles d'entiers comme exemple simple:

setA : {1, 2, 3, 4} setB : {2, 4, 6, 8}

Nous pouvons montrer les ensembles sous forme de diagramme en mettant simplement les valeurs dans des cercles:

Des diagrammes comme ceux-ci sont connus sous le nom de diagrammes de Venn et nous donnent un moyen utile de montrer les interactions entre les ensembles comme nous le verrons plus tard.

2.2. L'intersection des ensembles

Le terme intersection désigne les valeurs communes de différents ensembles .

Nous pouvons voir que les entiers 2 et 4 existent dans les deux ensembles. Donc, l'intersection de setA et setB est 2 et 4 car ce sont les valeurs communes à nos deux ensembles.

setA intersection setB = {2, 4}

Afin de montrer l'intersection dans un diagramme, nous fusionnons nos deux ensembles et mettons en évidence la zone commune à nos deux ensembles:

2.3. L'union des ensembles

Le terme union signifie combiner les valeurs de différents ensembles .

Créons donc un nouvel ensemble qui est l'union de nos ensembles d'exemples. Nous savons déjà que nous ne pouvons pas avoir de valeurs en double dans un ensemble. Cependant, nos ensembles ont des valeurs en double (2 et 4). Ainsi, lorsque nous combinons le contenu des deux ensembles, nous devons nous assurer de supprimer les doublons. Nous nous retrouvons donc avec 1, 2, 3, 4, 6 et 8.

setA union setB = {1, 2, 3, 4, 6, 8}

Encore une fois, nous pouvons montrer l'union dans un diagramme. Alors fusionnons nos deux ensembles et mettons en évidence la zone qui représente l'union:

2.4. Le complément relatif des ensembles

Le terme complément relatif désigne les valeurs d'un ensemble qui ne sont pas dans un autre . Elle est également appelée différence d'ensemble.

Créons maintenant de nouveaux ensembles qui sont les compléments relatifs de setA et setB .

relative complement of setA in setB = {6, 8} relative complement of setB in setA = {1, 3}

Et maintenant, mettons en évidence la zone de setA qui ne fait pas partie de setB . Cela nous donne le complément relatif de setB dans setA :

2.5. Le sous-ensemble et le sur-ensemble

Un sous-ensemble fait simplement partie d'un plus grand ensemble, et le plus grand ensemble est appelé un sur-ensemble. Lorsque nous avons un sous-ensemble et un sur-ensemble, l'union des deux est égale au sur-ensemble et l'intersection est égale au sous-ensemble.

3. Implémentation des opérations Set avec java.util.Set

Afin de voir comment nous effectuons des opérations d'ensemble en Java, nous allons prendre les ensembles d'exemple et implémenter l'intersection, l'union et le complément relatif. Commençons donc par créer nos exemples d'ensembles d'entiers:

private Set setA = setOf(1,2,3,4); private Set setB = setOf(2,4,6,8); private static Set setOf(Integer... values) { return new HashSet(Arrays.asList(values)); }

3.1. Intersection

Tout d'abord, nous allons utiliser la méthode retentionAll pour créer l'intersection de nos ensembles d'échantillons . Parce que retentionAll modifie directement l'ensemble, nous allons faire une copie de setA appelée intersectSet. Ensuite, nous utiliserons la méthode retentionAll pour conserver les valeurs qui sont également dans setB :

Set intersectSet = new HashSet(setA); intersectSet.retainAll(setB); assertEquals(setOf(2,4), intersectSet);

3.2. syndicat

Maintenant , nous allons utiliser la addAll méthode pour créer l'union de nos ensembles d'échantillons . La méthode addAll ajoute tous les membres de l'ensemble fourni à l'autre. Encore une fois, comme addAll met directement à jour l'ensemble, nous allons faire une copie de setA appelée unionSet , puis y ajouter setB :

Set unionSet = new HashSet(setA); unionSet.addAll(setB); assertEquals(setOf(1,2,3,4,6,8), unionSet);

3.3. Complément relatif

Finally, we'll use the removeAll method to create the relative complement of setB in setA. We know that we want the values that are in setA that don't exist in setB. So we just need to removeAll elements from setA that are also in setB:

Set differenceSet = new HashSet(setA); differenceSet.removeAll(setB); assertEquals(setOf(1,3), differenceSet);

4. Implementing Set Operations with Streams

4.1. Intersection

Let's create the intersection of our sets using Streams.

First, we'll get the values from setA into a stream. Then we'll filter the stream to keep all values that are also in setB. And lastly, we'll collect the results into a new Set:

Set intersectSet = setA.stream() .filter(setB::contains) .collect(Collectors.toSet()); assertEquals(setOf(2,4), intersectSet);

4.2. Union

Now let's use the static method Streams.concat to add the values of our sets into a single stream.

In order to get the union from the concatenation of our sets, we need to remove any duplicates. We'll do this by simply collecting the results into a Set:

Set unionSet = Stream.concat(setA.stream(), setB.stream()) .collect(Collectors.toSet()); assertEquals(setOf(1,2,3,4,6,8), unionSet);

4.3. Relative Complement

Finally, we'll create the relative complement of setB in setA.

As we did with the intersection example we'll first get the values from setA into a stream. This time we'll filter the stream to remove any values that are also in setB. Then, we'll collect the results into a new Set:

Set differenceSet = setA.stream() .filter(val -> !setB.contains(val)) .collect(Collectors.toSet()); assertEquals(setOf(1,3), differenceSet);

5. Utility Libraries for Set Operations

Now that we've seen how to perform basic set operations with pure Java, let's use a couple of utility libraries to perform the same operations. One nice thing about using these libraries is that the method names clearly tell us what operation is being performed.

5.1. Dependencies

In order to use the Guava Sets and Apache Commons Collections SetUtils we need to add their dependencies:

 com.google.guava guava 27.1-jre   org.apache.commons commons-collections4 4.3 

5.2. Guava Sets

Let's use the Guava Sets class to perform intersection and union on our example sets. In order to do this we can simply use the static methods union and intersection of the Sets class:

Set intersectSet = Sets.intersection(setA, setB); assertEquals(setOf(2,4), intersectSet); Set unionSet = Sets.union(setA, setB); assertEquals(setOf(1,2,3,4,6,8), unionSet);

Take a look at our Guava Sets article to find out more.

5.3. Apache Commons Collections

Now let's use the intersection and union static methods of the SetUtils class from the Apache Commons Collections:

Set intersectSet = SetUtils.intersection(setA, setB); assertEquals(setOf(2,4), intersectSet); Set unionSet = SetUtils.union(setA, setB); assertEquals(setOf(1,2,3,4,6,8), unionSet);

Take a look at our Apache Commons Collections SetUtils tutorial to find out more.

6. Conclusion

Nous avons vu un aperçu de la façon d'effectuer certaines opérations de base sur les ensembles, ainsi que des détails sur la façon d'implémenter ces opérations de différentes manières.

Tous les exemples de code peuvent être trouvés sur GitHub.