Je dirais que ces réponses manquent un truc.
Bloch, dans son ouvrage essentiel, merveilleux, concis Java efficace Dans son article 47, intitulé "Connaître et utiliser les bibliothèques", il déclare : "En résumé, ne réinventez pas la roue". Et il donne plusieurs raisons très claires pour ne pas le faire.
Il y a quelques réponses ici qui suggèrent des méthodes de CollectionUtils
dans la bibliothèque Apache Commons Collections mais aucun 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
}
Coupables : c'est-à-dire les éléments qui ne sont pas communs aux deux Lists
. Déterminer quels coupables appartiennent à list1
et à laquelle list2
est relativement simple en utilisant CollectionUtils.intersection( list1, culprits )
y 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 défaut du logiciel, mais que c'est inhérent à 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 d'Apache. L'un des avantages de l'utilisation de leur code est qu'il a été minutieusement testé, et que de nombreux cas limites et problèmes ont été anticipés et résolus. Vous pouvez copier et modifier ce code à votre guise si nécessaire.
NB J'ai d'abord été déçu qu'aucune des CollectionUtils
fournit une version surchargée vous permettant d'imposer votre propre Comparator
(vous pouvez donc redéfinir equals
selon vos besoins).
Mais à partir de collections4 4.0, il y a une nouvelle classe, Equator
qui "détermine l'égalité entre les objets de type T". En examinant le code source de collections4 CollectionUtils.java, il semble qu'ils l'utilisent avec certaines méthodes, mais pour autant que je puisse en juger, cela ne s'applique pas aux méthodes situées en haut du fichier, qui utilisent l'attribut CardinalityHelper
qui comprennent disjunction
y intersection
.
Je suppose que les gens d'Apache ne se sont pas encore penchés sur cette question parce qu'elle n'est pas triviale : il faudrait créer quelque chose comme une classe "AbstractEquatingCollection" qui, au lieu d'utiliser les caractéristiques inhérentes de ses éléments, utiliserait la méthode de calcul de l'équation. equals
y hashCode
devraient plutôt utiliser celles de Equator
pour toutes les méthodes de base, telles que add
, contains
etc. NB en fait quand on regarde le code source, AbstractCollection
ne met pas en œuvre add
ni ses sous-classes abstraites telles que AbstractSet
... vous devez attendre jusqu'à ce que les classes concrètes telles que HashSet
y ArrayList
avant add
est mis en œuvre. C'est un véritable casse-tête.
En attendant, surveillez cet espace, je suppose. La solution provisoire évidente serait d'envelopper tous vos éléments dans une classe d'enveloppe sur mesure qui utilise equals
y hashCode
pour mettre en œuvre le type d'égalité que vous voulez... puis manipuler Collections
de ces objets enveloppes.