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 CollectionUtilsla 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 list1et à qui list2est 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"} disjunctionavec {"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 CollectionUtilsméthodes ne propose une version surchargée vous permettant d'imposer la vôtre Comparator(afin que vous puissiez la redéfinir equalsen fonction de vos besoins).
Mais à partir de collections4 4.0, il existe une nouvelle classe, Equatorqui "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 CardinalityHelperclasse ... qui inclure disjunctionet 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 equalset les éléments inhérents à ses éléments hashCodede Equatorpour toutes les méthodes de base, tels que add, contains, etc. NB en fait , quand vous regardez le code source, AbstractCollectionne 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 HashSetet ArrayListavant addest 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 equalset hashCoded'implémenter le type d'égalité que vous souhaitez ... puis de manipuler Collectionsces objets wrapper.