Review request for initial lambda functions and utils
Steven Simpson
ss at comp.lancs.ac.uk
Wed Aug 10 13:16:35 PDT 2011
On 10/08/11 16:10, Kevin Bourrillion wrote:
> That's unfortunate. There is no valid reason under the sun that I can
> imagine for refusing to accept a Predicate<Object> when you wish to apply it
> to a String. That API is broken and should be fixed. (I believe the quote
> is, "An API should work.")
I came to the same conclusion while trying to answer another point.
Because there are no methods on Predicate which are blocked by using <?
super T>, anything that requires a Predicate<T> can and should be
written to accept a Predicate<? super T>. However, if an API fails to
do that, it's easy enough to have (say) a defender to downcast a Predicate:
interface Predicate<T> {
<U extends T> Predicate<U> down(Class<U> type)
default Predicates.down;
}
class Predicates {
static<T, U extends T> Predicate<U> down(Predicate<T> p, Class<U> type) {
return #{ t -> p.eval(t) }; // or p#eval
}
}
void api(Predicate<String> p) {
// Oops, should take a<? super String>.
}
Collection<String> coll;
Predicate<Object> p = Predicates.contains(coll);
api(p); // error
api(p.down(String.class));
If T/U is not a simple type, e.g. List/ArrayList<String>, I don't think
you can write down(ArrayList<String>.class) - unless that's a
forthcoming feature? - but since down() doesn't actually use the value
of 'type', you could use some sort of marker type instead, and write:
p.down(Marker.<ArrayList<String>>z())
More information about the lambda-dev
mailing list