220 votes

Obtenir la différence entre deux ensembles

Donc si j'ai deux ensembles :

Set<Integer> test1 = new HashSet<Integer>();
test1.add(1);
test1.add(2);
test1.add(3);

Set<Integer> test2 = new HashSet<Integer>();
test2.add(1);
test2.add(2);
test2.add(3);
test2.add(4);
test2.add(5);

Y a-t-il un moyen de les comparer et de n'avoir qu'un jeu de 4 et 5 renvoyés ?

11voto

Matt Watson Points 1435

J'ajoute une solution que j'ai récemment utilisée moi-même et que je n'ai pas vue mentionnée ici. Si vous disposez d'Apache Commons Collections, vous pouvez utiliser la fonction SetUtils#difference méthode :

// Returns all the elements of test2 which are not in test1
SetUtils.difference(test2, test1) 

Notez que selon la documentation, l'ensemble retourné est une vue non modifiable :

Renvoie une vue non modifiable contenant la différence des ensembles donnés, désignée par a \ b (ou a - b). La vue retournée contient tous les éléments de a qui ne sont pas membres de b.

Documentation complète : https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/SetUtils.html#difference-java.util.Set-java.util.Set-

3voto

Bojan Vukasovic Points 541

Juste pour donner un exemple (le système est en existingState et nous voulons trouver des éléments à supprimer (éléments qui ne sont pas dans newState mais sont présents dans existingState ) et les éléments à ajouter (éléments qui sont dans newState mais ne sont pas présents dans existingState ) :

public class AddAndRemove {

  static Set<Integer> existingState = Set.of(1,2,3,4,5);
  static Set<Integer> newState = Set.of(0,5,2,11,3,99);

  public static void main(String[] args) {

    Set<Integer> add = new HashSet<>(newState);
    add.removeAll(existingState);

    System.out.println("Elements to add : " + add);

    Set<Integer> remove = new HashSet<>(existingState);
    remove.removeAll(newState);

    System.out.println("Elements to remove : " + remove);

  }
}

produirait ce résultat :

Elements to add : [0, 99, 11]
Elements to remove : [1, 4]

3voto

HseJaR Points 35

L'ordre est important, car vous avez besoin de 4 et 5 qui est int (pas Integer), Utilisez test2.removeAll(test1) .

1voto

Josh M Points 4212

Si vous utilisez Java 8, vous pouvez essayer quelque chose comme ceci :

public Set<Number> difference(final Set<Number> set1, final Set<Number> set2){
    final Set<Number> larger = set1.size() > set2.size() ? set1 : set2;
    final Set<Number> smaller = larger.equals(set1) ? set2 : set1;
    return larger.stream().filter(n -> !smaller.contains(n)).collect(Collectors.toSet());
}

1voto

user14811990 Points 11

Vous pouvez créer une union en utilisant .addAll(), et une intersection en utilisant .retainAll(), des deux ensembles et utiliser .removeIf(), pour supprimer l'intersection (ou l'élément dupliqué) de l'union.

HashSet union = new HashSet(group1);
union.addAll(group2);

System.out.println("Union: " + union);

HashSet intersection = new HashSet(group1);
intersection.retainAll(group2);

System.out.println("Intersection: " + intersection);

HashSet difference = new HashSet(union);
difference.removeIf(n -> (difference.contains(intersection)));

System.out.println("Difference: " + difference);

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