Vendetta against Java Streams :: Jan 11, 2020

I like Java Streams as much as the next guy, but I can’t say that my experience using them has been all sunny. Here’s the long list of problems I’ve had with Streams during the last few years I’ve used them:

Stream<Path> paths = Files.list(...)
                          .filter(Files::isRegularFile);
for (Path p : paths) {
  ...
}

There was a proposal by Stewart Marks of Oracle to fix this, but Stream’s push model is in fundamental contrast with Iterable’s pull model. Not surprisingly, the proposal hasn’t been implemented.


Now lets consider the benefits Stream provides:


Maybe there are some points you disagree with, and maybe some workarounds, but think of the big picture here. Streams are just like the crufty GO4 design patterns you learn in college. By overloading the abstraction, we arrive at a solution that constrains the code we write, while muddying debugging and performance. So why does java.util.Stream even exist? Maybe it’s a fig leaf for the starry-eyed purely-functional undergrads (addicts?), who would rather struggle implementing Quick Sort than build software that makes money. Which was me at one point, I ashamedly admit. In any case I think the OpenJDK developers did a good job building Stream. It is much better than Scala’s approach in its standard library, but I will be avoiding both nonetheless.