I need to sift Collections according to contents of other Collections. Usually, I would have used the Collection.retainAll()
method.
Unfortunately, the equality of the domain objects I am handling is rather volatile, depending on the comparison context. Thus, I cannot rely on equals/hashCode
.
My next reflex was to use a custom Comparator
, but I was unable to find any methods supporting what I had in mind. Implementing the functionality is not a problem but I feel like reinventing the wheel here.
Have I missed something in the API? Other frameworks (not too esoteric) like commons are welcome too.
And if not, what optimizations would make my straightforward impl (creating a list of all Objects inside both Collections by going over all items of both Collections in n^2) a good one?

- 60,521
- 48
- 179
- 224
3 Answers
Suggest using Guava's filter. Alternative is to roll your own retainAllBy(sourceCollection, Comparator)
.

- 22,406
- 7
- 62
- 73
-
could by done by wrapping a collection with a Predicate and then filtering. Sounds good. Thank you – kostja Oct 17 '11 at 16:41
Have I missed something in the API?
There is nothing in the Java Collection Framework that do a retainAll
by anything else then the standard equals
implementation.
Strongly depending on your usecase you can do it this way:
Create a Wrapper Object, that can be wrapped about your Objects, but with the equals
method you need. And then use that wrappers to do the retainAll
afterwards you need to unwrap the objects from the resulting collection.
But this way has two drawbacks:
- lots of objects will be created
- it does only work correct if the
equals
method of the wrapper is still a valid equals method in terms of the java doc for equals methods.

- 118,862
- 56
- 287
- 383
-
Thanks, I was almost sure about the Collection/s API itself, but just couldnt believe it :) Maybe there's another possibility (like commons or sth like that). I updated the question to extend to other libs – kostja Oct 17 '11 at 15:16
Guava has a cumbersome solution to this problem, the Equivalence
concept. You wrap your objects in an equivalence using Equivalence.wrap()
, store the wrapped versions in collections and thereby make the collections use your custom equals / hashcode logic.
I (and others) have requested Equivalence-based sets and maps, but unfortunately the Guava team suggests that the above route should be taken instead.

- 292,901
- 67
- 465
- 588
-
+1: that was the API i was looking for while writing there is no support in core java – Ralph Oct 17 '11 at 15:21
-
1sounds rather complicated, makes me feel quite well off, using my rusty n^2 iteration method ;) Thank you. Guava seems really worth the effort though. – kostja Oct 17 '11 at 16:45