简体   繁体   中英

Using Java Predicate and Lambda

Why does the below code return Predicate<String> and not boolean ?

My understanding is that the !s.isEmpty() check here is going against the Predicate boolean test(T t); The return type here is boolean .

So in my lambda should my nonEmptyStringPredicate not be of type boolean ? Obviously, it's not, I'm just trying to understand why it's not.

Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty();

A Predicate gets in this case a String as parameter and returns a boolean . In case we don't write it as lambda it would look like this:

Predicate<String> somePredicate = new Predicate<String>() {
    @Override
    public boolean test(String string) {
        return !string.isEmpty();
    }
};

If you really are willing to get a boolean though from the Predicate , you can use its test method:

Predicate<String> nonEmptyStringPredicate = s -> !s.isEmpty();
boolean val = nonEmptyStringPredicate.test("any"); // true

Predicate on the other hand is just a FunctionalInterface , that you've represented using a lambda expression.

Lambda is like an anonymous class, so this:

Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty();

Is like:

Predicate<String> nonEmptyStringPredicate = new Predicate<String>() {
    public boolean test(String s) {
        return !s.isEmpty();
    }
}

Why does the below code return Predicate and not boolean?

This is because the type of the function (String s) -> !s.isEmpty() is a Predicate<String> , at this point you're simply defining a function (which says "given a String as input return a boolean value indication whether it's empty or not).

Note that at this point you're not evaluating anything hence the result is not a boolean but rather a function .

Definition of FI from the doc:

Functional interfaces provide target types for lambda expressions and method references. Each functional interface has a single abstract method, called the functional method for that functional interface, to which the lambda expression's parameter and return types are matched or adapted. Functional interfaces can provide a target type in multiple contexts, such as assignment context, method invocation, or cast context:

in order to get the "boolean result" you're seeking, you must first invoke the "functional method". example:

Predicate<String> nonEmptyStringPredicate = s -> !s.isEmpty();
boolean result = nonEmptyStringPredicate.test(""); 

A predicate always returns a boolean so the only interesting value here is the input parameter which is a String.

See: https://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html

It returns a predicate because on the left hand side you declared predicate as return type, and on the right side you are returning the implementation of Predicate's test() method. When your code returns an object which is the inplementation of a functional interface (like in your case) you simply return the logic of its single abstract method, in this case test() So basically is as ifyou are returning this: Predicate<String> nonEmptyStringPredicate = new Predicate { @Override boolean test(String input) { return input.isEmpty() } } When you write the code as you wrote it, the compiler 'knows' that !s.isEmpty() is the logic of method test , it basically tells you "hey give me just the logic, i dont need the boilerplate code" Btw is good practice to use method reference, you can replace !s.isEmpty() with !String::isEmpty

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM