3

What is the best, cheapest, performantest way to achive the following:

I do have a Collection of Objects myObject, which provide a method returning a Set of Integers. I want to add all the items inside the sets into a new set.

LinkedList<myObject>  ll = new LinkedList<>();

    //fill the list bla bla

Set<Integer> result = ll.stream()
    .map(f -> f.getTheSet())
    .flatMap(Set::stream)
    .collect(Collectors.toCollection(TreeSet::new));

System.out.println(result.toString());

is there a better way of getting a resulting set containing all integers from all objects? I would like to avoid "unpacking the set" with the flatMap command. Instead i think about something like .addAll or does it in the end not matter, because .addAll unpacks anyway?

Misha
  • 27,433
  • 6
  • 62
  • 78
Joel
  • 1,725
  • 3
  • 16
  • 34

2 Answers2

14

You can collect using addAll with a 3-argument collect:

Set<Integer> result = ll.stream()
        .map(MyObject::getTheSet)
        .collect(HashSet::new, Set::addAll, Set::addAll);

HashSet::new makes a new container, Set::addAll adds each set into the container, 2nd Set::addAll merges two containers if this stream were to be run in parallel.

(or use TreeSet::new if you specifically want a TreeSet)

Misha
  • 27,433
  • 6
  • 62
  • 78
  • works, but can you explain, what acually happens using `.collect(HashSet::new, Set::addAll, Set::addAll)`? – Joel Aug 11 '15 at 00:24
  • 2
    I added a brief explanation and a link to the 3-argument collect javadoc. I think It explains it better than I can. See if that makes sense to you – Misha Aug 11 '15 at 00:31
1

Instead i think about something like .addAll or does it in the end not matter, because .addAll unpacks anyway?

TreeSet.addAll() has an optimized codepath for adding Collections that implement SortedSet assuming they have the same sort order.

Caveat: This is an undocumented implementation detail and thus subject to change.

You could easily have found this information yourself simply looking at the JDK source code, which is included in the src.zip shipped with the JDK.

Community
  • 1
  • 1
the8472
  • 40,999
  • 5
  • 70
  • 122
  • 2
    Interesting addition. Note though this codepath works only when you add to an empty `TreeSet`, so it may be applicable for the first non-empty stream element only. – Tagir Valeev Aug 11 '15 at 08:54
  • @TagirValeev right, but for parallel streams that could still make a difference for all the leaf tasks. – the8472 Aug 11 '15 at 09:43