Search code examples
javalistlambdajava-8collectors

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


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?


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