Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collectors.toUnmodifiableList in java-10

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)));
like image 301
Eugene Avatar asked Mar 05 '18 09:03

Eugene


People also ask

What does collectors toList do in Java?

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) .

What is collector interface in Java?

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.

What is the difference between collector and collectors in Java?

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.

What is collect method in Java?

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.


2 Answers

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.

like image 112
Eugene Avatar answered Oct 04 '22 22:10

Eugene


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 throw NullPointerException if it is presented with a null 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.

like image 25
Naman Avatar answered Oct 04 '22 22:10

Naman