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 CollectionUtils
der 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 list1
und die zu list2
relativ 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 CollectionUtils
Methoden eine überladene Version bietet, mit der Sie Ihre eigene auferlegen können Comparator
(damit Sie sie equals
für Ihre Zwecke neu definieren können ).
Aus Sammlungen4 4.0 gibt es jedoch eine neue Klasse, Equator
die "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 CardinalityHelper
Klasse ... verwenden umfassen disjunction
und 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 equals
und hashCode
Methoden ihrer Elemente diese verwenden müsste der Equator
für alle grundlegenden Methoden, wie zum Beispiel add
, contains
usw. NB in der Tat , wenn Sie auf den Quellcode schauen, AbstractCollection
nicht implementiert add
, noch seine abstrakte Subklassen wie AbstractSet
... Sie bis in die konkreten Klassen wie warten HashSet
und ArrayList
vor add
ist 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 equals
und hashCode
implementiert ... und dann Collections
diese Wrapper-Objekte zu manipulieren .