[java:S6204] Improve suggestions

Qube: Community 9.9

The Java rule S6204 suggests to replace the use of

new ArrayList<>().stream().collect( Collectors.toList() );

with

new ArrayList<>().stream().toList();

More precisely it suggests “… when unmodifiable list needed”. In the inline hint from Lint it just says “Replace this usage of ‘Stream.collect(Collectors.toList())’ with ‘Stream.toList()’”. This leads you in a wrong direction. Hence the text should be improved.

First of all the Java API is a bit odd here.

Stream.toList() should do the same thing, that Stream.collect( Collectors.toList() ) does. But it doesn’t. The first unfortunately produces an unmodifiable List, the latter has no guaratee about that. At least there is Collectors.toUnmodifiableList(), which implies, that Collectors.toList() does the opposite. Two methods for the same pupopse from the very same framework should do the same thing.

Ok this is not your problem. But thing is, that rule S6204 does not reflect that enough.

The short hint from Lint just wants me to use Stream.toList(), which is a bad replacement, if I usually expect the list to be mutable (which Collectors.toList() used to do). So the short hint should somehow mention a solution for mutable and one of immutable to not lead you in the wrong direction.

And the rule description should not call Collectors.toUnmodifiableList() non compliant, since Stream.toList() might be a good replacement for that. But it is not for Collectors.toList(). And APIs should always be even, which Stream.toList() with the lack of Stream.toUnmodifiableList() is not, which Collectors.toList() and Collectors.toUnmodifiableList() is in theory, but documentation is not.

Of course there should be an attempt to fix that in JDK. Stream.toList() should guarantee a modifiable list and there should be Stream.toUnmodifiableList() for the opposite.

Hello @mfroehlich,

Rule S6204 intent is to use unmutable lists instead of mutable lists whenever possible. Specifically, the rule correctly suggests replacing stream.collect(Collectors.toList()); with stream.toList(); when there is no modification detected on the returned list, and thus, it is incorrect to define it as a mutable list.

Please provide a code example or reproducer if the rule doesn’t behave accordingly.

Cheers,
Angelo