Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to chain predicates with `and` using different type parameter?

I am learning Java 8 lambdas. Can I join two predicates, with different type parameter, using and method in Predicate interface?

This is my code:

Predicate<Integer> pc = (iv) -> iv > 20;
Predicate<String> pL = (is) -> is.length() > 5;
System.out.println("The predicate result for pc is: " + pc.test(25));
System.out.println("===========");
System.out.println("The predicate result with both condition true: " + pc.and(pL.test("abcd")));
like image 537
Sumon Bappi Avatar asked Dec 02 '25 11:12

Sumon Bappi


1 Answers

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.

like image 195
StandByUkraine Avatar answered Dec 03 '25 23:12

StandByUkraine



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!