No, you can not chain predicates of different types, unless the chained predicate also accepts the type of the original predicate.
Looking at the signature, you can easily see that:
and(Predicate<? super T> other)
or(Predicate<? super T> other)
You can chain predicates:
Predicate<Person> isMale = p -> p.isMale();
Predicate<Person> isAdult = p -> p.age() >= AGE_OF_MATURITY;
Predicate<Person> isAdultMale = isAdult.and(isMale);
You can only chain predicates that accept at least (thats what the ? super T
says) the same type as the original predicate:
Predicate<Object> hasWeirdHashCode = o -> o.hashCode() == 0;
Predicate<Person> nonsense = isMale.and(hasWeirdHashCode);
If you want to test different types (A
, B
), you need to provide them separately:
Predicate<A> propertyOfA = [...];
Predicate<B> propertyOfB = [...];
BiPredicate<A,B> propertyOfAnB = (a, b) ->
propertyOfA.test(a) && propertyOfB.test(b);
If you need more than two different types, you need to roll your own, custom TriPredicate
, QuadPredicate
and so on functional interfaces, which should be straight-forward to implement.