Streams are not very well designed IMHO. That's why their usage remains limited. Much more useful and robust libraries are possible on top of Java lambdas support.
Since everyone is now on Java 11 (and many on Java 8 still), we will only really see the records used widely in five years or so.
The modules stuff was a huge mistake in my opinion. Some people tend to like them in theory, but in practice they absolutely destroyed the adoption of newer Java versions and set Java 11 back by 10 years (literally).
Never blame people who try to solve real problems with your stuff. Better get your ego out of their way.
On the topic of Streams, the big issue that always crops up is exceptions. Streams and Exceptions are nearly incompatible with tacked on constructs that are painful to use. Any IO oriented program will have to face the issue of what happens to the Stream if an Exception is thrown.
An other thing is java's lack of tuples. All the time I'm reaching for some kind of ad-hoc grouping/touple but have to resort to using something from Apache or Spring or (perhaps abusing) Map.Entry<K,V>
Record types does make that a lot easier. They aren't quite as ad-hoc as in other languages, but this:
record Foo(int a, String b) {}
is a lot less to type than static final class Foo {
private final int a;
private final String b;
public final Foo(int a, String b) {
this.a = a;
this.b = b;
}
public int a() {
return a;
}
public String b() {
return b;
}
public int hashCode() {
return Objects.hashCode(a, b);
}
public boolean equals(Object o) {
if (o == null) return false;
if (o == this) return true;
if (o instanceof Foo f) {
return a == f.a && Objects.equals(b, f.b);
}
return false;
}
public String toString() {
return getClass().getSimpleName() + "[ a = " + a + ", " + "b = " + b + "]";
}
}What indeed caused breakage was the encapsulation effort that blocks unrestricted access to JVM internals, and that one was not even fully and forcibly turned on until Java 17.
You can see how such features are not super popular to the extent of widespread non-adoption of Java 11 even 10 years after its release.
I initially liked the idea of adding functional paradigms to the language, when the dust has settled all it does is create a sort of nasty Cronenberg language with most the drawbacks of both paradigms and few of the benefits of either.