I would say that these answers miss the trick.
Flea, in his basic, wonderful and concise book, Effective Java, says in paragraph 47 โKnow and use libraries,โ โTo summarize, don't reinvent the wheel.โ And he gives some very clear reasons why not.
Here are a few answers that suggest methods from CollectionUtils from CollectionUtils Apache Commons Collections, but none of them have found the most beautiful and elegant way to answer this question :
Collection<Object> culprits = CollectionUtils.disjunction( list1, list2 ); if( ! culprits.isEmpty() ){
Culprits : that is, elements that are not common to both Lists . Determining which culprits belong to list1 and which list2 is relatively simple using CollectionUtils.intersection( list1, culprits ) and CollectionUtils.intersection( list2, culprits ) .
However, it tends to fall apart in cases like {"a", "a", "b"} disjunction with {"a", "b", "b"} ... except that it is not a software failure , but inherent in the subtleties / ambiguities of the desired task.
NB. At first, I was disappointed that none of the CollectionUtils methods provides an overloaded version that allows you to impose your own Comparator (so that you can override equals to suit your goals).
But from collection4 4.0 there is a new class, Equator which "defines equality between objects of type T". When they look at the source code of collection4 CollectionUtils.java they seem to use this with some methods, but as far as I can tell, this does not apply to methods at the top of the file using the CardinalityHelper class ... which include disjunction and intersection .
I assume that the Apache people have not reached this point yet because it is not trivial: you need to create something like the class "AbstractEquatingCollection", which instead of using the methods inherent in its equals and hashCode elements will have to use those from Equator for all the main methods such as add , contains , etc. In fact, when you look at the source code, AbstractCollection does not implement add , nor does its abstract subclasses such as AbstractSet ... you have to wait for specific classes such as HashSet and ArrayList to be implemented before add . Pretty headache.
I believe that while watching this space. An obvious intermediate solution would be to wrap all your elements in a special wrapper class that uses equals and hashCode to implement the type of equality you want, and then manipulate the Collections these wrapper objects.