I need to extract a number of unique elements from a collection given a certain criteria. E.g. if I have a collection with [ (a1,t1,v1), (a2,t2,v2),…,(an,tx,vy) ]
I would like to get a1, t5, v8.
With Guava, I can have a Predicate for each (e.g. IsA1 implements Predicate …) and then use Iterables.find(collection, predicate) to locate each element. That’s ok, but it potentially loops through the whole collection for each predicate.
I could combine the predicates into one using Predicates.or(…) and use Iterables.filter, but the I’ll then have to search the resulting iterable for each single particular element I need.
What I would like to have is a function -let’s call it “locate”- that would take the element collection, a list of predicates and produce a map of (predicate -> element)
<T> Map<Predicate<? super T>, T> locate(Collection<T>, Collection<Predicate<? super T>)
I’ve rolled my own as I could not find it, but it’s such a common case that I think I just didn’t find it yet.
My version for reference:
public static <T> Map<Predicate<? super T>,T> locateUnique(Iterable<T> col, Collection<Predicate<? super T>> predicates) {
HashMap<Predicate<? super T>, T> result = Maps.newHashMap();
for (T t:col) {
for (Predicate<? super T> p:predicates) {
if (p.apply(t)){
result.put(p, t);
}
}
}
return result;
}
Is there a out-of-the-box way to do this? I guess there should be 2 versions for completeness:
locateUnique(...) -> Map<Predicate,T>
locate(...) -> MultiMap<Predicat,T>
Guava team member here. The preferred way to do this is exactly the way you describe — rolling your own method — although depending on the
equalsmethod ofPredicateis a little risky.I’m pretty confident that this is nowhere near as common a case as you describe, though, given that we’re already pretty stingy on functional idioms.