Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 Streams - Map Multiple Object of same type to a list using streams

Is it possible to do the below mentioned steps using streams in a better way ?

Set<Long> memberIds = new HashSet<>();
marksDistribution.parallelStream().forEach(marksDistribution -> {
        memberIds.add(marksDistribution.getStudentId());
        memberIds.add(marksDistribution.getTeacherId());
      });

instanceDistribution.getStudentId() and instanceDistribution.getTeacherId() are both of type Long.

It might be possible that this kind of question is asked but I am not able to understand it. In simple yes or no. If yes/no, then how and bit explanation. And if possible kindly, discuss the efficiency.

like image 305
balboa_21 Avatar asked Dec 11 '22 13:12

balboa_21


2 Answers

Yes, you can use flatMap to map a single element of your Stream into a Stream of multiple elements, and then flatten them into a single Stream :

Set<Long> memberIds = 
    marksDistribution.stream()
                     .flatMap (marksDistribution -> Stream.of(marksDistribution.getStudentId(), marksDistribution.getTeacherId()))
                     .collect(Collectors.toSet());
like image 111
Eran Avatar answered Jan 28 '23 12:01

Eran


You can use the 3-args version of collect:

Set<Long> memberIds = 
    marksDistribution.parallelStream()
                     .collect(HashSet::new, 
                              (s, m) -> {
                                   s.add(m.getStudentId());
                                   s.add(m.getTeacherId());
                               }, Set::addAll);

Your current version may produce wrong results, since you are adding elements in parallel in a non-thread safe collection. So it may be possible that you have multiple times the same value in the set.

like image 31
Alexis C. Avatar answered Jan 28 '23 10:01

Alexis C.