关闭Java 8 Stream

时间:2016-08-01 11:52:47

标签: java java-8 java-stream

如果我们像list.stream().filter(....).collect(..).....一样使用Java 8 Stream,它何时关闭此流?

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

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

4 个答案:

答案 0 :(得分:43)

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

来自Stream documentation

  

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

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

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

答案 1 :(得分:4)

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

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));
}

答案 2 :(得分:3)

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

流是非常通用的API;关键是它表示数据流没有,要求数据的使用者了解数据的来源。

关闭不需要关闭的流没有成本;无法关闭需要关闭的流可能会导致严重问题。您如何确定当前正在使用不需要关闭的数据流的正在编写的代码是否会从不重新用于需要关闭的其他类型的流?

我刚刚完成了大量的代码重构,这些代码曾经使用内存数据库来代替SQL后端。有问题的代码大量使用了流,这是有充分理由的。将JDBC结果集封装在流中意味着我可以(...我认为)很容易实现我的目标。但是...我的新流封装了需要关闭的资源,而旧流则不需要。由于原始开发人员(在本例中为我,我是在踢自己)没有关闭流,因此需要大量乏味的调试。

答案 3 :(得分:0)

关闭IO流有问题。 flatmap操作将关闭流。 如果您这样做,则会引发异常。

try (Stream<Path> s = Files.walk(p, 1)) {
    return s.flatMap(Stream::of);
} catch (IOException ignore) {
}

请参阅https://stackoverflow.com/a/34832694/7170627

混淆是否关闭IO流。