In Java 8 Streams
were introduced to support chaining of operations over collections in a functional style. The most common way to
save a result of such chains is to save them to some collection (usually List
). To do so there is a terminal method collect
that can be used with a library of Collectors
. The key problem is that .collect(Collectors.toList())
actually returns a
mutable kind of List
while in the majority of cases unmodifiable lists are preferred. In Java 10 a new collector appeared to return an
unmodifiable list: toUnmodifiableList()
. This does the trick but results in verbose code. Since Java 16 there is now a better variant to
produce an unmodifiable list directly from a stream: Stream.toList()
.
This rule raises an issue when "collect" is used to create a list from a stream.
Noncompliant code example
List<String> list1 = Stream.of("A", "B", "C")
.collect(Collectors.toList()); // Noncompliant
List<String> list2 = Stream.of("A", "B", "C")
.collect(Collectors.toUnmodifiableList()); // Noncompliant
Compliant solution
List<String> list1 = Stream.of("A", "B", "C").toList(); // Compliant
List<String> list2 = Stream.of("A", "B", "C")
.collect(Collectors.toList()); // Compliant, the list2 needs to be mutable
list2.add("X");