Chandler
Chandler

Reputation: 3295

Java 8 : Stream.filter not running as expected

Given:

    List<String> str = Arrays.asList ("my", "pen", "is", "your", "pen");
    Predicate<String> test = s -> {
        int i = 0;
        boolean result = s.contains ("pen");
        System.out.print((i++) + ":");
        return result;
    };

This prints: 0:0:

    str.stream().filter(test).findFirst();

And this prints 0:0:0:0:0:

    str.stream().filter(test).collect(Collectors.toList());

What confuses me is, no matter it is findFirst or collect, no matter the terminal operation is short-circuiting or not, they both should iterate through each item in the list, right?

So why "0:" is printed twice, not just once, not 5 times, in the first example findFirst?

Upvotes: 0

Views: 1130

Answers (2)

Misha
Misha

Reputation: 28163

What confuses me is, no matter it is findFirst or collect, no matter the terminal operation is short-circuiting or not, they both should iterate through each item in the list, right?

Ability to return without examining the entire stream is exactly what makes an operation (like findFirst) short-circuiting. See Streams javadoc.

Streams documentation actually makes no promises about how or whether your predicate will be evaluated. It just guarantees that it will return the first element of the stream that matches the predicate.

Upvotes: 6

Andres Sacco
Andres Sacco

Reputation: 670

The idea of the first Stream is iterate to find the first occurrence of "pen", so the Predicate iterates the array until finds the first element which matches the condition of the filter. For that reason, you see only two "0:". Official documentation

Upvotes: 2

Related Questions