I have two methods that return length's of strings in a list as follows;
private Stream<Integer> method1(List<String> list) {
try (final Stream<String> myStream = list.stream()) {
return myStream.map(String::length);
}
}
and
private Stream<Integer> method2(List<String> list) {
try (final Stream<String> myStream = list.stream()) {
return myStream.map(String::length).flatMap(Stream::of);
}
}
when I try to consume the resulting stream of either of the methods with;
List<Integer> collect = method1(list).collect(Collectors.toList());
or
List<Integer> collect = method2(list).collect(Collectors.toList());
I get
Exception in thread "main" java.lang.IllegalStateException: source already consumed or closed
Now I'm aware that using a stream in a try-with-resources block is not common. But in my real code I'm using Stream<Path> paths = Files.walk(Path.of(myPath))
in try-with-resources. And in the documentation of Files.walk(..)
method it says
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.
The code above is just an example to show the problem.
My question is why my streams are closed although I use map
and flatMap
to return a new stream. Am I wrong to expect that these two methods return new Stream
instance hence only the myStream
is closed but not the returned one from the map
operation? I have a vague understanding of monads but do map
and flatMap
methods' behaviors mean Stream
is not a real monad?