Given a Java function which uses a stream:
List<String> function(List<String> input) {
Stream<String> a = input.parallelStream();
Stream<String> b = a.map(c -> c.toString());
return b.collect(Collectors.toList());
}
Now, I want to control whether the mapping is performed by a parameter. Eclipse/the compiler gives me a warning: Resource leak: 'a' is never closed
List<String> function(List<String> input, boolean doMap) {
Stream<String> a = input.parallelStream(); // Resource leak: 'a' is never closed
Stream<String> b = doMap ? a.map(c -> c.toString()) : a;
return b.collect(Collectors.toList());
}
I can work around this with a try-with-resources statement:
List<String> function(List<String> input, boolean doMap) {
try (Stream<String> a = input.parallelStream()) {
Stream<String> b = doMap ? a.map(c -> c.toString()) : a;
return b.collect(Collectors.toList());
}
}
My question is: Why can there be resource leaks at all when I work with streams instead of for-loops? Why is there a resource leak if I only optionally add the mapping step? (Why isn’t there a resource leak in the first version of the function?) Is it “dangerous” to compose processing streams conditionally? What am I missing?