java 8的forEach在关闭流时的奇怪行为

huangapple go评论71阅读模式
英文:

java 8 forEach strange behaviour when closing stream

问题

我尝试在满足特定条件后通过关闭流来停止forEach,所以我进行了以下操作:

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);
    }
});

我期望以下输出:

inside for Each
1
inside for Each
2
inside for Each

但实际输出如下:

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

这意味着forEach在关闭流后继续执行,并且甚至没有抛出关于在流关闭后访问元素的异常。对于这种输出有什么解释吗?

英文:

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

Stream&lt;Integer&gt; stream = Stream.of(1, 2, 3, 4, 5);
		stream.forEach((e) -&gt; {
			System.out.println(&quot;inside for Each&quot;);
			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?

答案1

得分: 1

来自Stream的Javadoc

Stream具有BaseStream.close()方法并实现了AutoCloseable,但几乎所有流实例实际上在使用后都不需要被关闭。通常情况下,只有那些源是IO通道(例如通过Files.lines(Path, Charset)返回的流)的流需要关闭。大多数流是由集合、数组或生成函数支持的,它们不需要特殊的资源管理。(如果流确实需要关闭,可以在try-with-resources语句中将其声明为资源。)

即使源是IO通道,将其在forEach内部关闭并不是使用流的正确方式。

英文:

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.

答案2

得分: 0

Javadoc close():

> 关闭此流,导致调用针对此流管道的所有关闭处理程序。

由于没有在流中注册的关闭处理程序,此调用是无操作

英文:

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.

答案3

得分: 0

一个不同的方法,假设有一个有序流:

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

英文:

A different approach, assuming an ordered stream:

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

huangapple
  • 本文由 发表于 2020年9月12日 20:34:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/63860376.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定