Description
When using the generified AllPredicate class (in it's current form), it requires instantiation with all predicates having generic supertypes of the resultant combination:
public static <T> Predicate<T> getInstance(Predicate<? super T> ... predicates)
However, if one of the predicates was an InstanceOfPredicate, it could mean that every other predicate is able to be a super of the type that the instanceOfPredicate returns true for.
I propose that InstanceOfPredicate has a signature like:
public final class InstanceofPredicate<T,CT> implements Predicate<T>, Serializable ... public static <T,CT> InstanceofPredicate<T,CT> getInstance(Class<CT> type)
Where CT is the Type of the class that will be matched by the predicate.
AllPredicate should have constructors like:
public static <T,CT> AllPredicate<T,CT> getInstance(InstanceOfPredicate<?,CT>, Predicate<? super CT> ... predicates) public static <T,CT> AllPredicate<T,CT> getInstance(Class<CT>, Predicate<? super CT> ... predicates)
This would allow far nicer constructs of anonymous or simple predicates, and better type safety.
There would also be an additional method on AllPredicate:
public CT cast(Object matched)
That could be used as follows:
Predicate<Integer> predicate = AllPredicate.instanceOf(Integer.class, ...); Object o= ...; if (predicate.evaluate(o)){ Integer i = predicate.cast(o); //perform action }
Alternatively there could be a different method that attempts to coerce the type:
public CT transform(T t){ if (evaluate(t)){ return clazz.cast(t); //clazz is of type Class<CT> } return null; }
This could be used as follows:
Predicate<Integer> predicate = AllPredicate.instanceOf(Integer.class, ...); Object o= ...; Integer i = predicate.transform(o) if (i != null){ //perform action }
I prefer the cast() method; however, it would not re-evaluate the object, so would need documentation to be used correctly. The second method would allow it to be used as a transformer, but would substitute boolean checking to null checking.
Perhaps both are warranted. (The reason for the convenience methods are to not generate type-coercion warnings).