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?乍一看,.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这个问题可以扩展到其他stream方法,例如.findAny()。
stream.findAny() // Can I assume that I don't need to close the stream?
stream.onClose(() -> System.out.println("hi!")).findAny()`
// when the `onClose()` action will be called?这个问题的原因是,当需要显式关闭stream时,以及在不需要显式关闭它的情况下,onClose()定义的操作将在什么时候发生?
发布于 2017-10-11 13:15:42
终端操作从不关闭流。关闭必须手动完成。发生自动关闭的唯一地方是在flatMap操作中,通常是动态创建的子流的手动关闭将介于困难和不可能之间。
这也适用于Stream.spliterator()方法。在您的示例中,这没有什么区别,因为通过Stream.of(…)创建的流不需要关闭,默认情况下没有注册onClose()操作。
您必须查阅工厂方法的文档,以确定何时需要关闭流。比如Files#lines(Path, Charset)。
发布于 2017-10-11 13:13:56
在Java9中关闭Stream没有什么变化,如果需要释放底层资源,仍然需要手动完成。您不应该依赖垃圾收集器来完成它。文档仍然说:
流有一个
BaseStream.close()方法并实现AutoCloseable。在流关闭后对其进行操作将引发IllegalStateException。大多数流实例在使用后实际上不需要关闭,因为它们是由集合、数组或生成函数支持的,这些函数不需要特殊的资源管理。通常,只有源为IO通道的流(如由Files.lines(Path)**,返回的流)才需要关闭。如果流确实需要关闭,则必须将其作为资源打开,以便在运行完成后立即关闭。
发布于 2017-10-11 13:16:15
对spliterator()方法的调用返回该流的元素及其终端操作的分配器。
要回答您的问题-不,spliterator方法或出于这个原因,其他任何终端操作都不会关闭流。
这是为终端操作记录的-
在执行终端操作后,流管道被认为是消耗的,不能再使用.在几乎所有情况下,终端操作都是急切的,在返回之前完成对数据源的遍历和管道的处理。只有终端操作(
iterator()和spliterator()没有;这些操作是作为“转义舱口”提供的,以便在现有操作不足以执行任务时启用任意客户端控制的管道遍历。
另一方面,在关闭Stream时,文档声明:-
大多数流实例在使用后实际上不需要关闭,因为它们是由集合、数组或生成函数支持的,这些函数不需要特殊的资源管理。通常,只有源为IO通道的流(如
Files.lines(Path)返回的流)才需要关闭。
AutoCloseable声明要匹配它-
基类实现AutoCloseable是可能的,而且实际上也是常见的,即使不是它的所有子类或实例都持有可发布的资源。
这就是BaseStream如何扩展它,而close()对使用资源(如Files.lines(...) )的流的影响并不比流大得多。
然而,当使用支持基于I/O和非基于I/O的表单的流之类的工具时,在使用非基于I/O的表单时,通常没有必要使用带有资源的尝试块。
https://stackoverflow.com/questions/46688829
复制相似问题