What kind of List<E> does Collectors.toList() return?

JavaListLambdaJava 8Collectors

Java Problem Overview


I am reading [State of the Lambda: Libraries Edition][1], and am being surprised by one statement:

Under the section Streams, there is the following:

List<Shape> blue = shapes.stream()
                         .filter(s -> s.getColor() == BLUE)
                         .collect(Collectors.toList());

The document does not state what shapes actually is, and I do not know if it even matters.

What confuses me is the following: What kind of concrete List does this block of code return?

  • It assigns the variable to a List<Shape>, which is completely fine.
  • stream() nor filter() decide what kind of list to use.
  • Collectors.toList() neither specifies the concrete type of List.

So, what concrete type (subclass) of List is being used here? Are there any guarantees?

[1]: http://cr.openjdk.java.net/~briangoetz/lambda/lambda-libraries-final.html "State of the Lambda: Libraries Edition"

Java Solutions


Solution 1 - Java

> So, what concrete type (subclass) of List is being used here? Are there any guarantees?

If you look at the documentation of Collectors#toList(), it states that - "There are no guarantees on the type, mutability, serializability, or thread-safety of the List returned". If you want a particular implementation to be returned, you can use Collectors#toCollection(Supplier) instead.

Supplier<List<Shape>> supplier = () -> new LinkedList<Shape>();

List<Shape> blue = shapes.stream()
            .filter(s -> s.getColor() == BLUE)
            .collect(Collectors.toCollection(supplier));

And from the lambda, you can return whatever implementation you want of List<Shape>.

Update:

Or, you can even use method reference:

List<Shape> blue = shapes.stream()
            .filter(s -> s.getColor() == BLUE)
            .collect(Collectors.toCollection(LinkedList::new));

Solution 2 - Java

Navigating through Netbeans (Ctrl + Click), I landed in this code. It seems to be using an ArrayList as Supplier.

public static <T> Collector<T, ?, List<T>> toList() {
    return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
                               (left, right) -> { left.addAll(right); return left; },
                               CH_ID);
}

Solution 3 - Java

It doesn't matter, but the concrete type is non-generic as indeed all types are non-generic at runtime.

> So, what concrete type (subclass) of List is being used here? Are there any guarantees?

I don't think so, but ArrayList or LinkedList seem likely.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionskiwiView Question on Stackoverflow
Solution 1 - JavaRohit JainView Answer on Stackoverflow
Solution 2 - JavayamilmedinaView Answer on Stackoverflow
Solution 3 - JavaPeter LawreyView Answer on Stackoverflow