What kind of List<E> does Collectors.toList() return?
JavaListLambdaJava 8CollectorsJava 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()
norfilter()
decide what kind of list to use.Collectors.toList()
neither specifies the concrete type ofList
.
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.