关闭 Java 8 流

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38698182/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 20:31:49  来源:igfitidea点击:

Close Java 8 Stream

javajava-8java-stream

提问by Pau

If we use Java 8 Stream like list.stream().filter(....).collect(..).....When is it closed this stream?

如果我们使用 Java 8 Stream 像list.stream().filter(....).collect(..).....什么时候关闭这个流?

Is it good practice that we close the stream us as the next example?

作为下一个示例,我们关闭流是一种很好的做法吗?

Stream<String> stream = list.stream();
String result = stream.limit(10).collect(Collectors.joining(""));
stream.close();

采纳答案by kapex

It is generally not necessary to close streams at all. You only need to close streams that use IO resources.

通常根本没有必要关闭流。您只需要关闭使用 IO 资源的流。

From the Stream documentation:

流文档

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.)

流有一个BaseStream.close()方法和实现AutoCloseable,但几乎所有的流实例实际上不需要在使用后关闭。通常,只有源为 IO 通道的流(例如由 返回的流Files.lines(Path, Charset))才需要关闭。大多数流由集合、数组或生成函数支持,不需要特殊的资源管理。(如果流确实需要关闭,则可以在 try-with-resources 语句中将其声明为资源。)

Ifyou need to close a stream, then best practice would be to use the try-with-resources statement:

如果您需要关闭流,那么最佳做法是使用 try-with-resources 语句:

try ( Stream<String> stream = Files.lines(path, charset) ) {
    // do something
}

回答by 18446744073709551615

I have to add that by default streams are not closed at all!

我必须补充一点,默认情况下,流根本没有关闭!

    List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);

    // "--" is not printed at all:
    list.stream().onClose(()->System.out.println("--")).forEach(x -> System.out.println(x));

    System.out.println("with try(){}:");

    // "--" is printed:
    try (Stream<Integer> stream = list.stream() ) {
        stream.onClose(() -> System.out.println("--")).forEach(x -> System.out.println(x));
    }

回答by Jonathan Essex

Absolutely, by default you should close a stream.

当然,默认情况下您应该关闭流。

A stream is a very generic API; the whole point is that it represents a stream of data withoutrequiring the consumer of that data to understand where the data is coming from.

流是一个非常通用的 API;重点是它代表了一个数据流,而不需要该数据的消费者了解数据的来源。

Closing a stream which does not need closing has no cost; failing to close a stream which needs closing may cause serious issues. How sure are you that the code you are writing, which currently consumes a stream of data which does not require closing, will neverbe repurposed to consume a different type of stream that does require closing?

关闭不需要关闭的流没有成本;未能关闭需要关闭的流可能会导致严重的问题。您有多确定您正在编写的代码(当前使用不需要关闭的数据流)永远不会被重新用于使用需要关闭的不同类型的流?

I just finished refactoring a ton of code which used to use an in-memory database to use a SQL back-end instead. The code in question used streams a lot, and for good reason. Encapsulating a JDBC result set in a stream meant that I could (...I thought) achieve my goal quite easily. But... my new stream encapsulated a resource that required closing, whereas the old stream did not. Because the original developer (in this case me, I'm kicking myself) did not close the streams, much tedious debugging was required.

我刚刚完成了大量代码的重构,这些代码曾经使用内存数据库来代替 SQL 后端。有问题的代码经常使用流,这是有充分理由的。将 JDBC 结果集封装在流中意味着我可以(......我认为)很容易实现我的目标。但是……我的新流封装了一个需要关闭的资源,而旧流则没有。因为最初的开发人员(在这种情况下是我,我在踢自己)没有关闭流,所以需要进行繁琐的调试。