Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement method reference as a predicate?

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.

like image 591
user3303411 Avatar asked Mar 20 '26 07:03

user3303411


1 Answers

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.

like image 121
Andreas Avatar answered Mar 21 '26 21:03

Andreas



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!