How do you create an Unmodifiable
List/Set/Map with Collectors.toList/toSet/toMap
, since toList
(and the like) are document as :
There are no guarantees on the type, mutability, serializability, or thread-safety of the List returned
Before java-10 you have to provide a Function
with Collectors.collectingAndThen
, for example:
List<Integer> result = Arrays.asList(1, 2, 3, 4)
.stream()
.collect(Collectors.collectingAndThen(
Collectors.toList(),
x -> Collections.unmodifiableList(x)));
toList. Returns a Collector that accumulates the input elements into a new List . There are no guarantees on the type, mutability, serializability, or thread-safety of the List returned; if more control over the returned List is required, use toCollection(Supplier) .
public interface Collector<T,A,R> A mutable reduction operation that accumulates input elements into a mutable result container, optionally transforming the accumulated result into a final representation after all input elements have been processed.
Collection is used to represent a single unit with a group of individual objects whereas collections is used to operate on collection with several utility methods. Since java 8, collection is an interface with static as well as abstract and default methods whereas collections operate only with static methods.
collect() is one of the Java 8's Stream API's terminal methods. It allows us to perform mutable fold operations (repackaging elements to some data structures and applying some additional logic, concatenating them, etc.) on data elements held in a Stream instance.
With Java 10, this is much easier and a lot more readable:
List<Integer> result = Arrays.asList(1, 2, 3, 4)
.stream()
.collect(Collectors.toUnmodifiableList());
Internally, it's the same thing as Collectors.collectingAndThen
, but returns an instance of unmodifiable List
that was added in Java 9.
Additionally to clear out a documented difference between the two(collectingAndThen
vs toUnmodifiableList
) implementations :
The
Collectors.toUnmodifiableList
would return a Collector that disallows null values and will throwNullPointerException
if it is presented with anull
value.
static void additionsToCollector() {
// this works fine unless you try and operate on the null element
var previous = Stream.of(1, 2, 3, 4, null)
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
// next up ready to face an NPE
var current = Stream.of(1, 2, 3, 4, null).collect(Collectors.toUnmodifiableList());
}
and furthermore, that's owing to the fact that the former constructs an instance of Collections.UnmodifiableRandomAccessList
while the latter constructs an instance of ImmutableCollections.ListN
which adds to the list of attributes brought to the table with static factory methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With