Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to merge set use java stream with one line of code

I have two Set like this:

Set<String> set1;
Set<String> set2;

And I want to merge it with

Set<String> s = Stream.of(set1, set2).collect(Collectors.toSet());

and Error like this:

enter image description here

How can I convert Set to a serial of String object with flatMap? Is there any other solution that can accomplish this operation gracefully?

like image 236
hehe Avatar asked Aug 11 '20 06:08

hehe


People also ask

How do I combine two streams in Java?

concat() in Java. Stream. concat() method creates a concatenated stream in which the elements are all the elements of the first stream followed by all the elements of the second stream. The resulting stream is ordered if both of the input streams are ordered, and parallel if either of the input streams is parallel.

Can we use stream with set in Java?

Stream can be converted into Set using forEach(). Loop through all elements of the stream using forEach() method and then use set. add() to add each elements into an empty set.


3 Answers

If you insist on using Streams, you can use flatMap to convert your Stream<Set<String>> to a Stream<String>, which can be collected into a Set<String>:

Set<String> s = Stream.of(set1, set2).flatMap(Set::stream).collect(Collectors.toSet());
like image 192
Eran Avatar answered Nov 09 '22 00:11

Eran


You can use Stream.concat to merge the stream of two sets and collect as set.

Set<String> s = Stream.concat(set1.stream(), set2.stream()).collect(Collectors.toSet());
like image 43
Eklavya Avatar answered Nov 08 '22 22:11

Eklavya


There are couple of approach possible -

Concat

Set<String> s = Stream.concat(set1.stream(), set2.stream()).collect(Collectors.toSet());

It's get slightly ugly for more than 2 streams as we have to write

Stream.concat(Stream.concat(set1.stream(), set2.stream()), set3.stream())

Concat could be a problem for deeply concatenated stream. From documentation -

Use caution when constructing streams from repeated concatenation.Accessing an element of a deeply concatenated stream can result in deep call chains, or even StackOverflowException.

Reduce

Reduce can also be used to perform concatenation of stream as -

Set<String> s = Stream.of(set1.stream(), set2.stream()).reduce(Stream::concat)
  .orElseGet(Stream::empty).collect(Collectors.toSet());

Here Stream.reduce() returns optional that's the reason for orElseGet method call. It's also possible to contact multiple set as

Stream.of(set1.stream(), set2.stream(), set2.stream()).reduce(Stream::concat).orElseGet(Stream::empty).collect(Collectors.toSet());

Problem associated with deeply contacted stream applies to reduce as well

Flatmap

Flatmap can be used to get same result as -

 Set<String> s = Stream.of(set1, set2).flatMap(Set::stream).collect(Collectors.toSet());

To concat multiple stream you can use -

Set<String> s = Stream.of(set1, set2, set3).flatMap(Set::stream).collect(Collectors.toSet());

flatmap avoids StackOverflowException.

like image 25
Pankaj Avatar answered Nov 08 '22 23:11

Pankaj