Ich würde sagen, diese Antworten verpassen einen Trick.
Bloch sagt in seinem wesentlichen, wunderbaren, prägnanten, effektiven Java in Punkt 47, Titel "Die Bibliotheken kennen und benutzen", "Zusammenfassend, erfinden Sie das Rad nicht neu". Und er gibt mehrere sehr klare Gründe an, warum nicht.
Hier gibt es einige Antworten, die Methoden aus CollectionUtilsder Apache Commons Collections-Bibliothek vorschlagen, aber keine hat die schönste und eleganteste Art gefunden, diese Frage zu beantworten :
Collection<Object> culprits = CollectionUtils.disjunction( list1, list2 );
if( ! culprits.isEmpty() ){
// ... do something with the culprits, i.e. elements which are not common
}
Schuldige : dh die Elemente, die beiden nicht gemeinsam sind Lists. Die Festlegung , welche Schuldigen gehören list1und die zu list2relativ einfach verwendet CollectionUtils.intersection( list1, culprits )und CollectionUtils.intersection( list2, culprits ).
In Fällen wie {"a", "a", "b"} neigt es jedoch dazu, auseinanderzufallen.disjunction mit {"a", "b", "b"} auseinanderzufallen ... außer dies ist kein Fehler der Software, aber der Art der Feinheiten / Mehrdeutigkeiten der gewünschten Aufgabe inhärent.
Sie können den Quellcode (l. 287) jederzeit auf eine solche Aufgabe untersuchen, wie sie von den Apache-Ingenieuren erstellt wurde. Ein Vorteil der Verwendung ihres Codes besteht darin, dass er gründlich erprobt und getestet wurde und viele Randfälle und Fallstricke vorweggenommen und behandelt wurden. Sie können diesen Code bei Bedarf nach Herzenslust kopieren und optimieren.
NB Ich war zunächst enttäuscht, dass keine der CollectionUtilsMethoden eine überladene Version bietet, mit der Sie Ihre eigene auferlegen können Comparator(damit Sie sie equalsfür Ihre Zwecke neu definieren können ).
Aus Sammlungen4 4.0 gibt es jedoch eine neue Klasse, Equatordie "die Gleichheit zwischen Objekten vom Typ T bestimmt". Bei der Prüfung des Quellcodes von collection4 CollectionUtils.java scheinen sie dies mit einigen Methoden zu verwenden, aber soweit ich das beurteilen kann, gilt dies nicht für die Methoden oben in der Datei, die die CardinalityHelperKlasse ... verwenden umfassen disjunctionund intersection.
Ich vermute, dass die Apache-Leute noch nicht dazu gekommen sind, weil es nicht trivial ist: Sie müssten so etwas wie eine "AbstractEquatingCollection" -Klasse erstellen, die anstelle der inhärenten equalsund hashCodeMethoden ihrer Elemente diese verwenden müsste der Equatorfür alle grundlegenden Methoden, wie zum Beispiel add, containsusw. NB in der Tat , wenn Sie auf den Quellcode schauen, AbstractCollectionnicht implementiert add, noch seine abstrakte Subklassen wie AbstractSet... Sie bis in die konkreten Klassen wie warten HashSetund ArrayListvor addist implementiert. Ziemlich Kopfschmerzen.
In der Zwischenzeit diesen Raum beobachten, nehme ich an. Die naheliegende Zwischenlösung wäre, alle Ihre Elemente in eine maßgeschneiderte Wrapper-Klasse zu verpacken , die die gewünschte Gleichheit verwendet equalsund hashCodeimplementiert ... und dann Collectionsdiese Wrapper-Objekte zu manipulieren .