stream.spliterator() 是否关闭流?
Does the stream.spliterator() close the stream?
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()
将执行定义的操作?
Java9 中 Stream
的关闭没有任何变化。如果要释放底层资源,您仍然需要手动执行此操作。你永远不应该依赖垃圾收集器来做这件事。 docs 还是说:
Streams have a BaseStream.close()
method and implement AutoCloseable
. Operating on a stream after it has been closed will throw IllegalStateException
. Most stream instances do not actually need to be closed after use, as they are backed by collections, arrays, or generating functions, which require no special resource management. Generally, only streams whose source is an IO channel, such as those returned by Files.lines(Path)
, will require closing. If a stream does require closing, it must be opened as a resource within a try-with-resources statement or similar control structure to ensure that it is closed promptly after its operations have completed.
终端操作从不关闭流。关闭必须手动完成。唯一发生自动关闭的地方是在 flatMap
操作中,手动关闭通常即时创建的子流将介于困难和不可能之间。
这也适用于 Stream.spliterator()
方法。在您的示例中,这没有区别,因为通过 Stream.of(…)
创建的流不需要关闭,并且默认情况下没有注册 onClose()
操作。
您必须查阅工厂方法的文档才能确定何时需要关闭流。例如。像 Files#lines(Path, Charset)
.
另见 or Does Java 8 Stream.iterator()
auto-close the stream when it's done?
为此流的元素调用 spliterator()
method returns a Spliterator
,它是一个终端操作。
回答你的问题 - 不,其他 终端操作 的 spliterator
方法或为此目的 none 也不 关闭 流。
这代表 terminal operations 记录为 -
After the terminal operation is performed, the stream pipeline is
considered consumed, and can no longer be used.... In almost all cases, terminal operations
are eager, completing their traversal of the data source and
processing of the pipeline before returning. Only the terminal
operations iterator()
and spliterator(
) are not; these are provided as
an "escape hatch" to enable arbitrary client-controlled pipeline
traversals in the event that the existing operations are not
sufficient to the task.
另一方面,关闭 Stream
文档指出:-
Most stream instances do not actually need to be closed after use, as
they are backed by collections, arrays, or generating functions, which
require no special resource management. Generally, only streams whose
source is an IO channel, such as those returned by Files.lines(Path)
,
will require closing.
AutoCloseable
状态匹配它-
It is possible, and in fact common, for a base class to implement
AutoCloseable even though not all of its subclasses or instances will
hold releasable resources.
这就是 BaseStream 对其进行扩展的方式,close()
的影响远不及使用 Files.lines(...)
.
等资源的流
However, when using facilities such as Stream that support both
I/O-based and non-I/O-based forms, try-with-resources blocks are in
general unnecessary when using non-I/O-based forms.
方法stream.spliterator()
不会关闭Stream
,就像没有其他终端操作一样。您可能知道也可能不知道,如果您需要关闭 Stream
,那仍然是一个很大的争论。由于各种原因,我个人希望除了 spliterator()
和 iterator()
之外的所有终端操作都隐式关闭 Stream
。这样做没有什么坏处,因为大多数实现只会做 nothing.
您可以在 java.util.stream.AbstractPipeline
中找到一种实现。调用stream.onClose(action)
时添加的关闭动作将在调用stream.close()
时调用。
我不能告诉你什么时候 Stream
明确需要关闭,因为当前的政策是在 returns 和 Stream
的方法上记录它,比如 [=22] =]:
The returned stream contains a reference to an open directory. The directory is closed by closing the stream.
...
This method must be used within a try-with-resources statement or
similar control structure to ensure that the stream's open directory
is closed promptly after the stream's operations have completed.
当你调用stream.spliterator()
时,返回的Spliterator
可能是惰性的(参见AbstractPipeline.lazySpliterator(..)
),因此仍然需要对原始Stream
的元素进行操作.如果在遍历 Spliterator
的元素之前关闭 Stream
,您可能会遇到异常,或者 Spliterator
根本不再运行。
public static void main(final String[] args) throws IOException {
try (final Stream<Path> stream = Files.list(Paths.get(""))) {
stream.onClose(() -> System.out.println("stream closed"));
final Spliterator<Path> split = stream.spliterator();
/*
* uncomment this to see what happens when you close the
* stream before you traverse the spliterator
*/
// stream.close();
split.forEachRemaining(System.out::println);
}
}
现在的问题是,如果你想要returns一个Spliterator
的方法,调用者没有close()
可以在[=24=上调用的方法].
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()
将执行定义的操作?
Java9 中 Stream
的关闭没有任何变化。如果要释放底层资源,您仍然需要手动执行此操作。你永远不应该依赖垃圾收集器来做这件事。 docs 还是说:
Streams have a
BaseStream.close()
method and implementAutoCloseable
. Operating on a stream after it has been closed will throwIllegalStateException
. Most stream instances do not actually need to be closed after use, as they are backed by collections, arrays, or generating functions, which require no special resource management. Generally, only streams whose source is an IO channel, such as those returned byFiles.lines(Path)
, will require closing. If a stream does require closing, it must be opened as a resource within a try-with-resources statement or similar control structure to ensure that it is closed promptly after its operations have completed.
终端操作从不关闭流。关闭必须手动完成。唯一发生自动关闭的地方是在 flatMap
操作中,手动关闭通常即时创建的子流将介于困难和不可能之间。
这也适用于 Stream.spliterator()
方法。在您的示例中,这没有区别,因为通过 Stream.of(…)
创建的流不需要关闭,并且默认情况下没有注册 onClose()
操作。
您必须查阅工厂方法的文档才能确定何时需要关闭流。例如。像 Files#lines(Path, Charset)
.
另见 Stream.iterator()
auto-close the stream when it's done?
为此流的元素调用 spliterator()
method returns a Spliterator
,它是一个终端操作。
回答你的问题 - 不,其他 终端操作 的 spliterator
方法或为此目的 none 也不 关闭 流。
这代表 terminal operations 记录为 -
After the terminal operation is performed, the stream pipeline is considered consumed, and can no longer be used.... In almost all cases, terminal operations are eager, completing their traversal of the data source and processing of the pipeline before returning. Only the terminal operations
iterator()
andspliterator(
) are not; these are provided as an "escape hatch" to enable arbitrary client-controlled pipeline traversals in the event that the existing operations are not sufficient to the task.
另一方面,关闭 Stream
文档指出:-
Most stream instances do not actually need to be closed after use, as they are backed by collections, arrays, or generating functions, which require no special resource management. Generally, only streams whose source is an IO channel, such as those returned by
Files.lines(Path)
, will require closing.
AutoCloseable
状态匹配它-
It is possible, and in fact common, for a base class to implement AutoCloseable even though not all of its subclasses or instances will hold releasable resources.
这就是 BaseStream 对其进行扩展的方式,close()
的影响远不及使用 Files.lines(...)
.
However, when using facilities such as Stream that support both I/O-based and non-I/O-based forms, try-with-resources blocks are in general unnecessary when using non-I/O-based forms.
方法stream.spliterator()
不会关闭Stream
,就像没有其他终端操作一样。您可能知道也可能不知道,如果您需要关闭 Stream
,那仍然是一个很大的争论。由于各种原因,我个人希望除了 spliterator()
和 iterator()
之外的所有终端操作都隐式关闭 Stream
。这样做没有什么坏处,因为大多数实现只会做 nothing.
您可以在 java.util.stream.AbstractPipeline
中找到一种实现。调用stream.onClose(action)
时添加的关闭动作将在调用stream.close()
时调用。
我不能告诉你什么时候 Stream
明确需要关闭,因为当前的政策是在 returns 和 Stream
的方法上记录它,比如 [=22] =]:
The returned stream contains a reference to an open directory. The directory is closed by closing the stream. ...
This method must be used within a try-with-resources statement or similar control structure to ensure that the stream's open directory is closed promptly after the stream's operations have completed.
当你调用stream.spliterator()
时,返回的Spliterator
可能是惰性的(参见AbstractPipeline.lazySpliterator(..)
),因此仍然需要对原始Stream
的元素进行操作.如果在遍历 Spliterator
的元素之前关闭 Stream
,您可能会遇到异常,或者 Spliterator
根本不再运行。
public static void main(final String[] args) throws IOException {
try (final Stream<Path> stream = Files.list(Paths.get(""))) {
stream.onClose(() -> System.out.println("stream closed"));
final Spliterator<Path> split = stream.spliterator();
/*
* uncomment this to see what happens when you close the
* stream before you traverse the spliterator
*/
// stream.close();
split.forEachRemaining(System.out::println);
}
}
现在的问题是,如果你想要returns一个Spliterator
的方法,调用者没有close()
可以在[=24=上调用的方法].