This tutorial explains how to use Java 8’s predefined collector returned by
Collectors.toCollection() method with examples. It first explains the definition of the static
toCollection() method, followed by a quick explanation of its working, and then shows how to use Collector returned by
Collectors.toCollection() using two Java 8 code examples.
Collectors.toCollection() method is defined with the following signature –
public static <T, C extends Collection<T>> Collector<T, ?, C> toCollection(Supplier<C> collectionFactory)
– only input parameter is
collectionFactory which is an instance of a SupplierClick to Read Tutorial on Supplier Functional Interface functional interface.
– output is a Collector with result containerClick to Read tutorial explaining collector internals incl. ‘result container’ as a
Collection of type
How the Collector returned by Collectors.toCollection() method works
The collector returned by
Collector.toCollection() method stores(collects) the stream elements in an object of a subtype of
Which specific type of subtype
Collection to use is specified to the collector using the
collectionFactory input parameter which is a
Supplier functional interface. A
Supplier’s task is to supply objects of a given type. In this case, the supplier passed to the
toCollection() method needs to ‘supply’ a concrete
Collection instance in order for the collector to work.
So, when the stream elements reach the
Stream.collect() method with a toCollection collector, the
Collector invokes the
Supplier, in return gets an object of the
Collection subtype it supplies, and then collects the stream elements into the supplied
Collection object. This
Collection object, containing the collected stream elements, is then returned as the output of the processed stream.
To complete our understanding of how the toCollection Collector works, let us see couple of Java 8 code examples which show the collector in action.OUTPUT of the above code Explanation of the code
ToCollectionCollectorclass contains a static list of
- In the
main()method a stream of
Employeeobjects is created using
- Stream of employees is then pipelined to the
collect()terminal operationClick to Read Tutorial explaining intermediate & terminal Stream operations.
- To the
Collectors.toCollection()method is passed as a parameter.
- toCollection collector is invoked with the input “
LinkedList::new”, which is a method reference
Click to Read Tutorial on Java 8’s Method References, to the
LinkedList’s default constructor .
- toCollection collector then collects the
Employeeobjects in the stream in an instance of
LinkedListand returns this linked list as the output of stream processing.
LinkedListis assigned to a parameter named
employeeLinkedList. The size of the linked list and its contents are then printed. As expected, the linked list has
Employeeobjects, and all the 5 objects are printed with their name and age.
(Note – The
Employee class and
employeeList objects with their values remain the same as the previous code usage example and hence are not shown again in example 2 below for brevity.)
Employeeobjects in the stream are collected, with the
Supplierinput to the
toCollection()method being the method reference to the default
- The collected
Employeeobjects are then returned in a
HashSetinstance and assigned to
- The count of collected employees is then printed along with the
- However, this time the number of employee objects in
employeeHashSetcomes out to be
- If you observe closely in the output to see which
Employeeobject is missing, then you will see that 1 out of 2
"Tom Jones"(employee name) objects is missing. This is however the correct output. This is because, both the “Tom Jones” objects have the same
age, their salary being different. But
Employeeonly checks for
ageto determine equality. As a result, the
HashSetinsertion logic finds these two objects to be equal and only stores one of them, as a
HashSetcannot store duplicate objects by design.