Combine stream of Collections into one Collection - Java 8

20,918

Solution 1

This functionality can be achieved with a call to the flatMap method on the stream, which takes a Function that maps the Stream item to another Stream on which you can collect.

Here, the flatMap method converts the Stream<Collection<Long>> to a Stream<Long>, and collect collects them into a Collection<Long>.

Collection<Long> longs = streamOfCollections
    .flatMap( coll -> coll.stream())
    .collect(Collectors.toList());

Solution 2

You could do this by using collect and providing a supplier (the ArrayList::new part):

Collection<Long> longs = streamOfCollections.collect(
    ArrayList::new, 
    ArrayList::addAll,
    ArrayList::addAll
);

Solution 3

You don't need to specify classes when not needed. A better solution is:

Collection<Long> longs = streamOfCollections.collect(
    ArrayList::new,
    Collection::addAll,
    Collection::addAll
);

Say, you don't need an ArrayList but need a HashSet, then you also need to edit only one line.

Share:
20,918
Andrew Mairose
Author by

Andrew Mairose

Full stack Java and web developer experienced in Spring Framework, Hibernate, JPA, Angular JS, etc.

Updated on March 28, 2020

Comments

  • Andrew Mairose
    Andrew Mairose about 4 years

    So I have a Stream<Collection<Long>> that I obtain by doing a series of transformations on another stream.

    What I need to do is collect the Stream<Collection<Long>> into one Collection<Long>.

    I could collect them all into a list like this:

    <Stream<Collection<Long>> streamOfCollections = /* get the stream */;
    
    List<Collection<Long>> listOfCollections = streamOfCollections.collect(Collectors.toList());
    

    And then I could iterate through that list of collections to combine them into one.

    However, I imagine there must be a simple way to combine the stream of collections into one Collection<Long> using a .map() or .collect(). I just can't think of how to do it. Any ideas?

  • Alexis C.
    Alexis C. almost 9 years
    You could also use a method reference: .flatMap(Collection::stream)
  • Vivin Paliath
    Vivin Paliath about 8 years
    @Desik Most definitely - it's what I use these days. At the time I was just learning the new streaming API.
  • Jordan Mackie
    Jordan Mackie over 5 years
    @Desik why is it better performing than the accepted answer?
  • Desik
    Desik over 5 years
    @JordanMackie Because there are less intermediate operations, and no temporary objects created. In this solution you don't call stream() on every collection.