Stream的javadoc说明:
Streams有一个BaseStream.close()方法并实现AutoCloseable,但几乎所有的流实例实际上都不需要在使用后关闭.通常,只有源为IO通道的流(例如Files.lines(Path,Charset)返回的流)才需要关闭.大多数流都由集合,数组或生成函数支持,不需要特殊的资源管理.(如果流确实需要关闭,则可以在try-with-resources语句中将其声明为资源.)
因此,绝大多数情况下,人们可以在单行中使用Streams,collection.stream().forEach(System.out::println);
但是对于Files.lines
和其他资源支持的流,必须使用try-with-resources语句或泄漏资源.
这让我觉得容易出错并且不必要.因为Streams只能迭代一次,所以在我看来,没有一个迭代后Files.lines
不应该关闭输出的情况,因此实现应该只是在任何终端操作结束时隐式调用close .我错了吗?
是否stream.spliterator()
隐式关闭stream
,或者之后是否需要明确关闭它?
Stream<String> stream = Stream.of("a", "b", "c");
Spliterator<T> spliterator = stream.spliterator();
// Some low lever operation with the spliterator
stream.close(); // do we need to close?
Run Code Online (Sandbox Code Playgroud)
乍一看,似乎该.spliterator()
方法关闭了stream
,但没有调用stream.close()
.至少如果我在.spliterator()
调用方法后立即将其关闭,似乎不会影响分裂器操作.
Stream<String> stream = Stream.of("a", "b", "c").limit(2);
Spliterator<T> spliterator = stream.spliterator();
stream.close();
// Some low lever operation with the spliterator
Run Code Online (Sandbox Code Playgroud)
这个问题可以扩展到其他stream
方法,例如,.findAny()
.
stream.findAny() // Can I assume that I don't need to close the stream?
stream.onClose(() -> System.out.println("hi!")).findAny()`
// …
Run Code Online (Sandbox Code Playgroud)