Quelle est la meilleure façon d'obtenir le symétrique de la différence entre deux ensembles en java?
Je me demandais si il existe un moyen rapide/moyen propre pour obtenir le symétrique de la différence entre deux ensembles ?
J'ai:
Set<String> s1 = new HashSet<String>();
s1.add("a");
s1.add("b");
s1.add("c");
Set<String> s2 = new HashSet<String>();
s2.add("b");
J'ai besoin de quelque chose comme:
Set<String> diff = Something.diff(s1, s2);
//diff would contain ["a", "c"]
Juste pour préciser j'ai besoin de la symétrique différence.
- Quick&facile: Vous pourriez écrire Set<String> diff = new HashSet<String>(s1); diff.removeAll(s2);
- ce sera un échec pour S1={"a","b","c"},S2={"b","d"}. résultat devrait être {"a","c","d"}
- Si par "différence" (cf. secure.wikimedia.org/wikipedia/en/wiki/...) les OP signifiait symétrique différence, alors vous avez raison. Cependant, vous pouvez obtenir ce que (A - B) + (B - A), ou (A + B) - (Un bouchon B). Je ne connais pas de moyen plus rapide en java pour le mettre en œuvre.
- Java 8 et Java 11 : stackoverflow.com/a/52268640/1216775
Vous devez vous connecter pour publier un commentaire.
Vous pouvez utiliser certaines fonctions de la Google Goyave de la bibliothèque (qui est vraiment génial, je le recommande vivement!):
Javadoc différence() et symmetricDifference()
symmetricDifference()
fait exactement ce que vous demandez, maisdifference()
est également souvent utile.Deux méthodes retournent une vue en direct, mais vous pouvez par exemple faire appel
.immutableCopy()
sur l'ensemble résultant d'obtenir un non-changeant. Si vous ne voulez pas d'un point de vue, mais besoin d'un ensemble d'instance, vous pouvez les modifier, de les appeler.copyInto(s3)
. Voir SetView pour ces méthodes.HashSet
et unTreeSet
peut être problématique. À l'aide de la méthode avec deuxHashSet
s, ou deuxTreeSets
, etc. est fine.HashSet
et unTreeSet
, si lecompareTo()
méthode et laequals()
méthode des éléments d'accord les uns avec les autres (ce qui est fortement recommandé par leur documentation). De sorte que dans certains cas, la méthode ne peut pas garantir que la différence est calculée correctement, dans la plupart des cas pratiques, il fonctionnera très bien.Vous voulez le symétrique différence.
Si vous voulez une bibliothèque, Apache Commons CollectionUtils a
qui renvoie à un non-générique
Collection
.et Jeux De Goyave a
qui retourne un inmodifiable
Set
comme un génériqueSets.SetView
.Goyave est un peu plus moderne, en soutenant les génériques, mais l'une de ces travaux.
Si vous pouvez utiliser "Apache Commons Collections, vous êtes à la recherche pour
CollectionUtils.la disjonction(Collection de, Collection de b)
. Il retourne la différence symétrique de deux Collections.Si non, il suffit de soustraire (
removeAll
) l'intersection (retainAll
) des deux ensembles à l'union des deux (addAll
):Boucle à travers un ensemble et de les comparer.
C'est seulement
O(n)
d'une boucle sur l'un des ensembles. Considérer ce code:Et la
newSet
va maintenant contenir uniquement les entrées uniques à partir de deux ensembles. C'est rapide, parce que vous avez seulement besoin d'une boucle sur les éléments de l'un des ensembles et vous n'avez pas à créer des ensembles, sauf si vous explicitement besoin d'une copie.O(n)
pourHashSet
sans collision seulement. Pour TreeSets, tous les trois opérationsadd(key)
,contains(key)
etremove(key)
nécessiterait la recherche de l'arbre une fois, soit un ajout deO(n log n)
.}
Java 8 Solution
On peut écrire deux méthodes d'utilitaire (pour java 8 et avant) dans une classe
SetUtils (say)
comme:La méthode
add
renvoie false si l'élément existe déjà et méthode nier est utilisé pour nier le prédicat.Java 11
Nous avons un Prédicat#pas méthode de prédicat en Java 11 et pouvez l'utiliser comme:
Devrait fonctionner.