I have a method
<T> void f (Collection<T> c, T t)
Alas, sometimes I need to pass as the first arg not Collection but Collection<P> where P is a precursor for T, i.e., there is a P getter method returning a T.
So how do I modify my method to work with both Collection<P> and Collection<T> (in the latter case the getter is the identity)?
E.g.,
<T> boolean f (Collection<T> c, T t) {
for (T x : c) if (x.equals(t)) return true;
return false;
}
class Z { String a, b; }
I want to be able to use f to search Collection<Z> by either a or b:
f(Collection<Z> c1 ???searching by a???, "foo")
f(Collection<Z> c2 ???searching by b???, "bar")
I have no control over the implementation of T and P; in particular, I cannot make P inherit from T (and I don’t want to: as in Z above, I might want to search by different fields at different times).
I do not want to create an intermediate Collection<T> by mapping.
I want something like the common :key Lisp keyword argument.
How about using something like a interface for the predicate to check on equality. An example would be:
and then use the following function:
Then you could call it the following ways:
While this syntax is quite verbose it should fit your question. It will however get prettier in Java 8 when lambda functions will arrive.