2017-01-17 1 views
4

Возможно ли выполнить описанные ниже шаги с использованием потоков лучше?Java 8 Streams - Map Несколько объектов одного и того же типа для списка с использованием потоков

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

instanceDistribution.getStudentId() и instanceDistribution.getTeacherId() оба типа Long.

Возможно, этот вопрос задан, но я не могу его понять. В простых да или нет. Если да/нет, то как и бит объяснять. И если это возможно, обсудите эффективность.

ответ

4

Вы можете использовать 3-арг версию от сбора:

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

Ваша текущая версия может приводить к неправильным результатам, поскольку вы добавляете параллельные элементы в коллекцию, не связанную потоками. Таким образом, возможно, что у вас есть несколько раз то же значение в наборе.

+0

Вы можете обсудить эффективность и по сравнению с тем, что я сделал? –

+5

@ balboa_21 Проблема в том, что то, что вы сделали, является ошибочным. Прежде чем думать об эффективности, вы должны думать о правильности. Тем не менее, использование 'collect' - это канонический способ получить то, что вы хотите использовать потоки. –

+0

c: Спасибо за быстрый ответ. Хорошо, если возможно, я не использую parallelStream()?. –

6

Да, вы можете использовать flatMap для отображения одного элемента из ваших Stream в Stream из нескольких элементов, а затем сплющить их в один Stream:

Set<Long> memberIds = 
    marksDistribution.stream() 
        .flatMap (marksDistribution -> Stream.of(marksDistribution.getStudentId(), marksDistribution.getTeacherId())) 
        .collect(Collectors.toSet()); 
+0

Вы можете обсудить эффективность и по сравнению с тем, что я сделал? –

+4

@Eran 1+ от меня, если у вас есть jdk-9, вы можете использовать flatMapping collector: list.stream(). Collect (Collectors.flatMapping ((MarksDistribution md) -> Stream.of (md.getStudentId(), md.getTeacherId()), Collectors.toSet())); – Eugene

+1

@Eugene Ницца, мне, вероятно, стоит попробовать jdk-9 в ближайшее время. – Eran

Смежные вопросы