After reading https://www.airpair.com/java/posts/spring-streams-memory-efficiency, I am tempted to stream results out of a database, but as I discussed with a colleague (cfr. comment he added to that article), one needs to remember to use the try-with-resources construct to avoid any memory leaks.
Streams have a BaseStream. close() method and implement AutoCloseable , but nearly all stream instances do not actually need to be closed after use. Generally, only streams whose source is an IO channel (such as those returned by Files. lines(Path, Charset) ) will require closing.
IO Resources. Under the hood, this method opens a FileChannel instance and then closes it upon stream closure. Therefore, if we forget to close the stream, the underlying channel will remain open and then we would end up with a resource leak.
Non-Terminal operation : will transform a stream into another stream, such as filter(Predicate).
Yes you you should close it and you can close it if you pass it into a submethod. If you pass it into a Reader though, if you call close on the Reader it will also close the stream.
Because streams that require explicit resource release is actually a pretty unusual case. So we chose not to burden all stream execution with something that is only valuable for .01% of usages.
We made Stream Autocloseable so that you can release resources from the source if you want to, but this is where we stopped, and for a good reason.
Not only would doing this automagically burden the majority of users with extra work that they don't need, but this would also violate a general principle: he who allocates the resource is responsible for closing the resource. When you call
BufferedReader reader = ... reader.lines().op().op()...
you are the one opening the resource, not the stream library, and you should close it. In fact, since closing a stream resulting from calling an accessor method on some resource-holding object will sometimes close the underlying object, you probably don't want the stream closing the BufferedReader
for you -- you might want it to stay open after the call.
If you want to close the resource, this is easy too:
try (BufferedReader reader = ...) { reader.lines().op()... }
You're probably using streams in a particular way, so it probably seems "obvious" what streams should do -- but there are more use cases out there than yours. So rather than catering to specific use cases, we approached it from the general principle: if you opened the stream, and you want it closed, close it yourself, but if you didn't open it, it's not for you to close.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With