Question

I am reading State of the Lambda: Libraries Edition, 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?

Was it helpful?

Solution

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

OTHER TIPS

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);
}

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top