-2

I was trying to stop forEach after a certain condition is met by closing the stream, so I did the following

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
        stream.forEach((e) -> {
            System.out.println("inside for Each");
            if(e == 3) {
                stream.close();
            } else {
                System.out.println(e);
            }
        });

I was expecting the following output:

inside for Each  
1  
inside for Each  
2  
inside for Each  

but I got the following output:

inside for Each
1
inside for Each
2
inside for Each
inside for Each
4
inside for Each
5

which means that the forEach continued after closing the stream... it didn't even throw an exception about accessing an element after the stream is closed. Any explanation for that output?

Bhavye Mathur
  • 1,024
  • 1
  • 7
  • 25
  • 3
    java stream is not designed for this.https://stackoverflow.com/questions/23996454/terminate-or-break-java-8-stream-loop/23997320 – Mr Nobody Sep 12 '20 at 12:47
  • *Explanation:* There is no resource behind that stream, so `close()` is a no-op. – Andreas Sep 12 '20 at 13:25
  • Hint: when you are new to a specific concept, then research it. All java library classes have excellent documentation and there are many tutorials explaining their use. So: read the documentation first. Look into tutorials. But avoid making assumptions what this or that library call is supposed to do. – GhostCat Sep 12 '20 at 13:34

3 Answers3

1

From javadoc of Stream

Streams have a BaseStream.close() method and implement AutoCloseable, but nearly all stream instances do not actually need to be closed after use. Generally, only streams whose source is an IO channel (such as those returned by Files.lines(Path, Charset)) will require closing. Most streams are backed by collections, arrays, or generating functions, which require no special resource management. (If a stream does require closing, it can be declared as a resource in a try-with-resources statement.)

Even if the source is an IO channel, closing it inside a forEach is not the way to use streams.

Thiyagu
  • 17,362
  • 5
  • 42
  • 79
0

Javadoc of close():

Closes this stream, causing all close handlers for this stream pipeline to be called.

Since there no close handlers registered with the stream, the call is a no-op.

Andreas
  • 154,647
  • 11
  • 152
  • 247
  • if there is no close handlers, then why an exception is thrown when i called stream.close() then called stream.forEach(System.out::println) ? ..the exception message was saying that the stream is already closed. – Abdelrahman_Attya Sep 12 '20 at 15:35
  • @Abdelrahman_Attya Stream has a flag indicating if the stream is closed, and checks the flag at the beginning of forEach, not while the stream is processing. – Andreas Sep 12 '20 at 18:43
0

A different approach, assuming an ordered stream:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5); stream.takeWhile(n->n<3).forEach(System.out::println);

Pablo Fradua
  • 369
  • 1
  • 4
  • 16