Java 8 flatMapped 流在 try-with-resources 块中关闭
Java 8 flatMapped stream closed in try-with-resources block
我有两种方法 return 列表中字符串的长度,如下所示;
private Stream<Integer> method1(List<String> list) {
try (final Stream<String> myStream = list.stream()) {
return myStream.map(String::length);
}
}
和
private Stream<Integer> method2(List<String> list) {
try (final Stream<String> myStream = list.stream()) {
return myStream.map(String::length).flatMap(Stream::of);
}
}
当我尝试使用其中一种方法的结果流时;
List<Integer> collect = method1(list).collect(Collectors.toList());
或
List<Integer> collect = method2(list).collect(Collectors.toList());
我明白了
Exception in thread "main" java.lang.IllegalStateException: source already consumed or closed
现在我知道在 try-with-resources 块中使用流并不常见。但在我的真实代码中,我在 try-with-resources 中使用 Stream<Path> paths = Files.walk(Path.of(myPath))
。在 Files.walk(..)
方法的文档中它说
This method must be used within a try-with-resources statement or similar control structure to ensure that the stream's open directories are closed promptly after the stream's operations have completed.
上面的代码只是一个例子来说明问题。
我的问题是,尽管我使用 map
和 flatMap
到 return 新流,但为什么我的流被关闭了。我是否错误地期望这两种方法 return new Stream
实例因此只有 myStream
被关闭而不是来自 map
操作的 returned ?我对 monad 的理解很模糊,但是 map
和 flatMap
方法的行为是否意味着 Stream
不是真正的 monad?
一旦 try
块完成,stream
将关闭。
因为 Stream<T>
扩展了 BaseStream<T, Stream<T>>
而 BaseStream
扩展了 AutoCloseable
why the Stream instance I created in the block is also closed
因为在块中创建的新Stream
实例是链式嵌套
myStream
的流,将在 myStream
(外部流)关闭后立即关闭。您可以使用 onClose
验证它,如下所示,
privat Stream<Integer> method1(List<String> list) {
try (final Stream<String> myStream = list.stream()) {
Stream<Integer> integerStream = myStream.onClose(r)
.map(String::length).onClose(r1);
return integerStream;
}
}
Runnable r = ()->{
System.out.println("closed main stream...");
};
Runnable r1 = ()->{
System.out.println("closed map stream...");
};
我有两种方法 return 列表中字符串的长度,如下所示;
private Stream<Integer> method1(List<String> list) {
try (final Stream<String> myStream = list.stream()) {
return myStream.map(String::length);
}
}
和
private Stream<Integer> method2(List<String> list) {
try (final Stream<String> myStream = list.stream()) {
return myStream.map(String::length).flatMap(Stream::of);
}
}
当我尝试使用其中一种方法的结果流时;
List<Integer> collect = method1(list).collect(Collectors.toList());
或
List<Integer> collect = method2(list).collect(Collectors.toList());
我明白了
Exception in thread "main" java.lang.IllegalStateException: source already consumed or closed
现在我知道在 try-with-resources 块中使用流并不常见。但在我的真实代码中,我在 try-with-resources 中使用 Stream<Path> paths = Files.walk(Path.of(myPath))
。在 Files.walk(..)
方法的文档中它说
This method must be used within a try-with-resources statement or similar control structure to ensure that the stream's open directories are closed promptly after the stream's operations have completed.
上面的代码只是一个例子来说明问题。
我的问题是,尽管我使用 map
和 flatMap
到 return 新流,但为什么我的流被关闭了。我是否错误地期望这两种方法 return new Stream
实例因此只有 myStream
被关闭而不是来自 map
操作的 returned ?我对 monad 的理解很模糊,但是 map
和 flatMap
方法的行为是否意味着 Stream
不是真正的 monad?
一旦 try
块完成,stream
将关闭。
因为 Stream<T>
扩展了 BaseStream<T, Stream<T>>
而 BaseStream
扩展了 AutoCloseable
why the Stream instance I created in the block is also closed
因为在块中创建的新Stream
实例是链式嵌套
myStream
的流,将在 myStream
(外部流)关闭后立即关闭。您可以使用 onClose
验证它,如下所示,
privat Stream<Integer> method1(List<String> list) {
try (final Stream<String> myStream = list.stream()) {
Stream<Integer> integerStream = myStream.onClose(r)
.map(String::length).onClose(r1);
return integerStream;
}
}
Runnable r = ()->{
System.out.println("closed main stream...");
};
Runnable r1 = ()->{
System.out.println("closed map stream...");
};