As a side note, Collectors.toUnmodifiableList
just uses the implementation of List::of
that was added in java-9, the finisher for that implementation is:
list -> (List<T>)List.of(list.toArray()
where list
is just an ArrayList
; so your question just boils down to what is the difference between List::of
and Collections::unmodifiableList
(of course with the caveat that this is not specified and happens under the current implementation) and while I could detail some of the differences, there are already good ones (and many more if you search).
One point to note is how these different types handle null
s (the other point that one s actually a view, was already provided in the other answers):
List<Integer> left = Stream.of(1, 2, 3)
.collect(Collectors.collectingAndThen(
Collectors.toList(),
Collections::unmodifiableList));
System.out.println(left.contains(null));
List<Integer> right = Stream.of(1, 2, 3)
.collect(Collectors.toUnmodifiableList());
System.out.println(right.contains(null));
The last line of code will throw an Exception, you might not expect that at all.