Card 03/ 10
Streams Example: The Same Steps Over Lines Read From a File
The same filter, map and collect over a source that is not in memory and may be larger than memory.
A stream's source does not have to be a collection. Files.lines gives a stream of the lines of a file, read as the pipeline asks for them, and the same filter, map and toList work on it unchanged:
try (Stream<String> lines = Files.lines(path)) {
List<String> refs = lines
.filter(line -> !line.isBlank())
.map(line -> line.split(",")[0])
.toList();
}There is no list here at all. Files.lines produces a stream over a file that is read as the pipeline pulls from it, which is why a file of ten million lines does not need ten million lines of memory.
Put this beside the same filter, map and toList over an in-memory list, and the shared fact comes out: neither source was read until the terminal operation, the final step that asks for a result, ran, and neither stream can be run a second time. A stream is a description of work over a source, and the source can be anything that can produce elements one at a time.
← → move through sections and cards