How to implement method reference as a predicate?

user3303411 :

I am new to java8 and I was trying to understand this piece of code. This is the piece of code:

Stream.of("A", "B", "C").anyMatch(someObj.getStringValue()::equalsIgnoreCase)

someObj.getStringValue() references some object and the getStringValue() returns some String value.

What is the equivalent predicate of the method reference being passed into anyMatch(...)?

My understanding was this would be equivalent to:

Predicate<String> p = new Predicate<String>() {
    @Override
    public boolean test(String t) {
        return someObject.getStringValue().equalsIgnoreCase(t);
    }
}
Stream.of("A", "B", "C").anyMatch(p)

With this I get the error "Local variable someObject defined in an enclosing scope must be final or effectively final." Any explanation on this is appreciated.

Andreas :

The someObj.getStringValue() expression is evaluated outside, so equivalent code would be:

final String x = someObject.getStringValue();
Predicate<String> p = new Predicate<String>() {
    @Override
    public boolean test(String t) {
        return x.equalsIgnoreCase(t);
    }
}
Stream.of("A", "B", "C").anyMatch(p)

where the local variable x is "anonymous" too.

Because of this, someObject does not need to be effectively final.

You can verify this behavior for the lambda expression in a debugger, by putting a breakpoint inside getStringValue(). Even though the test() method is called 3 times (because the stream has 3 elements, and assuming no match), the getStringValue() method will only be called once.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=306286&siteId=1