Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

283
Views
When does a Java intermediate operation hit every element?

I'm confused by the way Java streams work, particularly as regard to short-circuiting. For an example of what confuses me, I cooked up the following example:

List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Optional<Integer> res = list.stream()
        .map(x -> {
            System.out.println("first map: " + x);
            return 2*x;
        })
        .sorted((a,b)-> {
            System.out.println("sorting " + a + " : " + b);
            return a - b;
        })
        .map(x -> {
            System.out.println("second map: " +  x);
            return 2*x;
        })
        .findAny();
System.out.println("found " + res.get());

with output

first map: 1
first map: 2
first map: 3
first map: 4
first map: 5
first map: 6
first map: 7
first map: 8
first map: 9
first map: 10
sorting 4 : 2
sorting 6 : 4
sorting 8 : 6
sorting 10 : 8
sorting 12 : 10
sorting 14 : 12
sorting 16 : 14
sorting 18 : 16
sorting 20 : 18
second map: 2
found 4

When executed, this code demonstrates that calling sorted in the middle forces the first map to apply to every element in the stream. However, the second map does not get applied to every element in the stream since findAny short-circuits it.

So basically my question is: what are the rules here? Why is Java smart enough to know it doesn't need to call the second map on every element of the stream but not smart enough to know that findAny at the end doesn't require it to actually sort anything.

I tried "reading the manual" on this, and it just isn't clear to me.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

That happens because streams are processing elements from the source lazily one at a time.

Each operation occurs only when it's needed.

In the case of sorting, stream dumps all the data from the source to memory because there's no way to sort elements peeking then one by one.

map --> sorted --> map --> findAny

The First-time map operation gets applied to all elements because it precedes the sorting operation.

After sorting is done, elements will be processed one at a time.

Terminal operation findAny is a short-circuit operation. And hence only the very first of all the elements will be peeked by the terminal operation, the second map operation needs to be applied only once.


Why is Java smart enough to know it doesn't need to call the second map on every element of the stream but not smart enough to know that findAny at the end doesn't require it to actually sort anything

Well, I guess because until now findAny() in the case of single-threaded execution still behaves exactly like findFirst(), which will require to do sorting in order to find the correct result.

You may try to play with sequential streams and find out that findAny() and findFirst() yield the same result.

I can't give you the answer to why it behaves in such away.

Java-doc says with caution about findAny()

The behavior of this operation is explicitly nondeterministic

Only if stream is being processed in parallel behavior of findAny() differs from findFirst().

findAny() could return an element that is peeked by any thread, while findFirst() guarantees to respect the initial order while providing the result.


https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/stream/Stream.html

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!