Powiedziałbym, że te odpowiedzi pomijają sztuczkę.
Bloch w swojej podstawowej, cudownej, zwięzłej Efektywnej Javie , mówi w pozycji 47, zatytułowanej „Poznaj i używaj bibliotek”, „Podsumowując, nie odkrywaj na nowo koła”. I podaje kilka bardzo wyraźnych powodów, dla których nie.
Jest tutaj kilka odpowiedzi, które sugerują metody z CollectionUtilsbiblioteki Apache Commons Collections, ale żadna nie znalazła najpiękniejszego, najbardziej eleganckiego sposobu odpowiedzi na to pytanie :
Collection<Object> culprits = CollectionUtils.disjunction( list1, list2 );
if( ! culprits.isEmpty() ){
}
Winowajcy : tj. Elementy, które nie są wspólne dla obu Lists. Określenie, do kogo należą, list1a do kogo winowajcy, list2jest stosunkowo proste przy użyciu CollectionUtils.intersection( list1, culprits )i CollectionUtils.intersection( list2, culprits ).
Jednak ma tendencję do rozpadania się w przypadkach takich jak {"a", "a", "b"} disjunctionz {"a", "b", "b"} ... z wyjątkiem tego, że nie jest to awaria oprogramowania, ale nieodłączne od charakteru subtelności / niejasności pożądanego zadania.
Zawsze możesz sprawdzić kod źródłowy (l. 287) dla takiego zadania, jak to zostało stworzone przez inżynierów Apache. Jedną z korzyści płynących z używania ich kodu jest to, że został on gruntownie wypróbowany i przetestowany, z wieloma skrajnymi przypadkami i problemami przewidzianymi i rozwiązanymi. W razie potrzeby możesz skopiować i ulepszyć ten kod według własnego uznania.
Uwaga: Na początku byłem rozczarowany, że żadna z CollectionUtilsmetod nie zapewnia przeładowanej wersji, umożliwiającej narzucenie własnej Comparator(dzięki czemu można przedefiniować equalsją tak, aby odpowiadała Twoim celom).
Ale z kolekcji4 4.0 jest nowa klasa, Equatorktóra „określa równość między obiektami typu T”. Podczas badania kodu źródłowego collections4 CollectionUtils.java wydaje się, że używają tego z niektórymi metodami, ale o ile wiem, nie ma to zastosowania do metod znajdujących się na początku pliku, przy użyciu CardinalityHelperklasy ... która obejmują disjunctioni intersection.
Przypuszczam, że ludzie z Apache jeszcze do tego nie doszli, ponieważ jest to nietrywialne: należałoby utworzyć coś w rodzaju klasy „AbstractEquatingCollection”, która zamiast używać elementów equalsi hashCodemetod jej elementów , musiałaby zamiast tego używać tych z Equatordla wszystkich podstawowych metod, takich jak add, containsitp. Uwaga: w rzeczywistości, gdy patrzysz na kod źródłowy, AbstractCollectionnie implementuje add, ani jego abstrakcyjnych podklas, takich jak AbstractSet... musisz poczekać, aż konkretne klasy takie jak HashSeti ArrayListwcześniej addjest zaimplementowane. Dość ból głowy.
Przypuszczam, że w międzyczasie obserwuj tę przestrzeń. Oczywistym tymczasowym rozwiązaniem byłoby umieszczenie wszystkich elementów w specjalnie zaprojektowanej klasie opakowania, która używa equalsi hashCodezaimplementuje taki rodzaj równości, jaki chcesz, a następnie manipulowanie Collectionstymi obiektami opakowania.