Je dirais que ces réponses manquent un truc.
Bloch, dans son essentiel, merveilleux et concis Effective Java , dit, au point 47, titre «Connaître et utiliser les bibliothèques», «Pour résumer, ne réinventez pas la roue». Et il donne plusieurs raisons très claires pourquoi pas.
Il y a quelques réponses ici qui suggèrent des méthodes de CollectionUtils
la bibliothèque Apache Commons Collections, mais aucune n'a repéré la manière la plus belle et la plus élégante de répondre à cette question :
Collection<Object> culprits = CollectionUtils.disjunction( list1, list2 );
if( ! culprits.isEmpty() ){
// ... do something with the culprits, i.e. elements which are not common
}
Les coupables : c'est-à-dire les éléments qui ne sont pas communs aux deux Lists
. Déterminer à quels coupables appartiennent list1
et à qui list2
est relativement simple en utilisant CollectionUtils.intersection( list1, culprits )
et CollectionUtils.intersection( list2, culprits )
.
Cependant, il a tendance à s'effondrer dans des cas comme {"a", "a", "b"} disjunction
avec {"a", "b", "b"} ... sauf que ce n'est pas un échec du logiciel, mais inhérente à la nature des subtilités / ambiguïtés de la tâche souhaitée.
Vous pouvez toujours examiner le code source (l. 287) pour une tâche comme celle-ci, tel que produit par les ingénieurs Apache. Un avantage de l'utilisation de leur code est qu'il aura été minutieusement essayé et testé, avec de nombreux cas extrêmes et des pièges anticipés et traités. Vous pouvez copier et modifier ce code à votre guise si nécessaire.
NB J'ai été au début déçu qu'aucune des CollectionUtils
méthodes ne propose une version surchargée vous permettant d'imposer la vôtre Comparator
(afin que vous puissiez la redéfinir equals
en fonction de vos besoins).
Mais à partir de collections4 4.0, il existe une nouvelle classe, Equator
qui "détermine l'égalité entre les objets de type T". À l'examen du code source de collections4 CollectionUtils.java, ils semblent l'utiliser avec certaines méthodes, mais pour autant que je sache, cela ne s'applique pas aux méthodes en haut du fichier, en utilisant la CardinalityHelper
classe ... qui inclure disjunction
et intersection
.
Je suppose que les gens d'Apache ne sont pas encore parvenus à cela parce que ce n'est pas trivial: vous devriez créer quelque chose comme une classe "AbstractEquatingCollection", qui au lieu d'utiliser les méthodes equals
et les éléments inhérents à ses éléments hashCode
de Equator
pour toutes les méthodes de base, tels que add
, contains
, etc. NB en fait , quand vous regardez le code source, AbstractCollection
ne met pas en oeuvre add
, ni ne les sous - classes abstraites telles que AbstractSet
... vous devez attendre jusqu'à ce que les classes concrètes telles que HashSet
et ArrayList
avant add
est implémenté. Un mal de tête.
En attendant, surveillez cet espace, je suppose. La solution provisoire évidente serait d'envelopper tous vos éléments dans une classe wrapper sur mesure qui utilise equals
et hashCode
d'implémenter le type d'égalité que vous souhaitez ... puis de manipuler Collections
ces objets wrapper.