Reputation: 3979
I'm trying to get this working :
Predicate<Integer> predicateInteger = i -> i>0;
System.out.println(predicateInteger.test(1)); // works and prints true
Now I'm trying to define another predicate like on predicateInteger
using equals :
// stmt below DOES NOT COMPILE : Target type of a lambda conversion must be an interface
Predicate<Integer> predicateEq = predicateInteger.equals(i -> new Boolean(true));
System.out.println(predicateEq.test(8));// I want this to print "TRUE" on equals .
What am I doing wrong here ?
Upvotes: 2
Views: 1633
Reputation: 3979
This helped me achieve what I want :
// when this is the first predicate:
Predicate<Integer> predicateInteger = i -> i>0;
// and when this second predicate compares with the first,
Predicate<Integer> predicateEq = predicateInteger.and(i -> i<6);
// then :
System.out.println(predicateEq.test(5));// prints true
Upvotes: 0
Reputation: 44476
This is not how predicates and functional interfaces (lambda expressions) in general. The Predicate
class has the only method boolean test(T t)
. The lambda expression is nothing different from an anonymous class implementation. Notice there is no equals
method, therefore the lambda expressions are not comparable (in terms of equality).
Predicate<Integer> predicateInteger = i -> i > 0;
Predicate<Integer> predicateInteger = new Predicate<Integer>() {
@Override
public boolean test(Integer i) {
return i > 0;
}
}
Actually, the Predicate#test
returns boolean
which can be directly printed out:
Predicate<Integer> integerPredicate = i -> i > 0;
System.out.println(integerPredicate.test(8)); // true
Seems you want to compare the result value to something else, defined with another Predicate
.
Predicate<Integer> integerPredicate = i -> i > 0;
Predicate<Object> resultPredicate = i -> true;
boolean result = integerPredicate.test(8) == resultPredicate.test("whatever");
System.out.println(result); // true
Note that, in fact, Predicate<Object> predicate = i -> true
is practically a Supplier
which returns a constant value regardless the input (actually, it has no input).
Predicate<Integer> integerPredicate = i -> i > 0;
Supplier<Boolean> resultSupplier = () -> true;
boolean result = integerPredicate.test(8) == resultSupplier.get();
System.out.println(result); // true
However, this makes no sense as long as the integerPredicate
can be printed out directly with no resultSupplier
.
Predicate<Integer> integerPredicate = i -> i > 0;
System.out.println(integerPredicate.test(8)); // true
... and we are back at the beginning.
The last thing that comes to my mind is to print out the result always on the method test
call. All you need is to define a decorator, that wraps the Predicate
delegate and submits an action on the test
method call using Consumer<Boolean
where Boolean
is the former predicate's result.
@AllArgsConstructor // constructor omitted (Lombok) for sake of brevity
public class CallbackPredicate<T> implements Predicate<T> {
private final Predicate<T> delegate;
private final Consumer<Boolean> callback;
@Override
public final boolean test(final T t) {
boolean result = delegate.test(t);
callback.accept(result);
return result;
}
}
Predicate<Integer> integerPredicate = new CallbackPredicate<>(
i -> i > 0, // Predicate<Integer>
System.out::println); // Callback
integerPredicate.test(8); // prints true
The predicates can be also chained using the AND
clause represented by the Predicate#and
method:
Predicate<Integer> largerThanZero = i -> i > 0;
Predicate<Integer> smallerThanSix = i -> i < 6;
Predicate<Integer> betweenZeroAndSix = largerThanZero.and(smallerThanSix);
System.out.println(betweenZeroAndSix.test(-5)); // false
System.out.println(betweenZeroAndSix.test(5)); // true
System.out.println(betweenZeroAndSix.test(15)); // false
Upvotes: 3