stream.spliterator() 是否关闭了流?

2022-09-03 01:40:42

是隐式关闭 了 ,还是之后需要显式关闭它?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()streamstream.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?

这个问题的原因是,当一个需要明确关闭时,以及在我不需要明确关闭它的情况下,定义的行为何时会发生,要有非常清楚的了解?streamonClose()


答案 1

终端操作从不关闭流。关闭必须手动完成。发生自动关闭的唯一位置是在操作中,通常动态创建的子流的手动关闭介于困难和不可能之间。flatMap

这也适用于该方法。在您的示例中,它没有区别,因为 via 创建的流不需要关闭,并且默认情况下没有注册任何操作。Stream.spliterator()Stream.of(…)onClose()

您必须查阅工厂方法的文档,以了解何时需要关闭流。例如,像Files#lines(Path,Charset)一样

另请参阅 Stream 上的 collect 操作是否会关闭流和底层资源?Java 8 Stream.iterator() 在完成后是否会自动关闭流?


答案 2

关于 Java 9 中 s 的关闭没有任何变化。如果应释放基础资源,则仍需要手动执行此操作。您永远不应该依赖垃圾回收器来执行此操作。文档仍然说:Stream

流有一个方法和实现。在流关闭后对其进行操作将抛出 。大多数流实例在使用后实际上并不需要关闭,因为它们由集合、数组或生成函数提供支持,不需要特殊的资源管理。通常,只有源是 IO 通道的流(例如 Files.lines(Path) 返回的流)才需要关闭。如果流确实需要关闭,则必须将其作为资源试用语句或类似控制结构中的资源打开,以确保在其操作完成后立即关闭流。BaseStream.close()AutoCloseableIllegalStateException


推荐