Est-il possible de mieux suivre les étapes mentionnées ci-dessous en utilisant les flux?

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

instanceDistribution.getStudentId() et instanceDistribution.getTeacherId() sont tous deux de type Long.

Il est possible que ce genre de question soit posée mais je ne suis pas en mesure de la comprendre. En simple oui ou non. Si oui / non, alors comment et peu d'explication. Et si possible, veuillez discuter de l'efficacité.

4
balboa_21 17 janv. 2017 à 13:21

2 réponses

Meilleure réponse

Vous pouvez utiliser la version 3-args de collect:

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

Votre version actuelle peut produire des résultats erronés, car vous ajoutez des éléments en parallèle dans une collection non thread-safe. Il est donc possible que vous ayez plusieurs fois la même valeur dans l'ensemble.

4
Alexis C. 17 janv. 2017 à 10:32

Oui, vous pouvez utiliser flatMap pour mapper un seul élément de votre Stream en un Stream de plusieurs éléments, puis les aplatir en un seul Stream:

Set<Long> memberIds = 
    marksDistribution.stream()
                     .flatMap (marksDistribution -> Stream.of(marksDistribution.getStudentId(), marksDistribution.getTeacherId()))
                     .collect(Collectors.toSet());
7
Eran 17 janv. 2017 à 10:24