【发布时间】:2020-04-30 23:20:31
【问题描述】:
我有两种方法可以返回列表中字符串的长度,如下所示;
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(..) 方法的文档中它说
此方法必须在 try-with-resources 语句或类似的控制结构中使用,以确保在流的操作完成后立即关闭流的打开目录。
上面的代码只是说明问题的一个例子。
我的问题是,尽管我使用 map 和 flatMap 返回一个新流,但为什么我的流已关闭。我期望这两种方法返回新的Stream 实例,因此只有myStream 被关闭而不是map 操作返回的实例,我错了吗?我对 monad 的理解很模糊,但 map 和 flatMap 方法的行为是否意味着 Stream 不是真正的 monad?
【问题讨论】:
-
不要使用try-with-resources,让调用者处理流的关闭
-
我在我的方法中为我的流使用 try-with-resources。然后我希望这个方法创建另一个流供方法调用者使用。
标签: java java-8 functional-programming java-stream monads