Как правильно заменить вложенный цикл for потоками в Java 8?

Изучая потоки и лямбды Java 8, я попытался заменить следующие вложенные циклы for на потоки:

List<Long> deskIds = new ArrayList<>();
for(ProvidedService memberService : service.getAllNodesDepthFirst()){
   for(Desk d : memberService.getDesks()){
     deskIds.add(d.getId());
   }
}

Цикл перебирает список объектов «ProvidedService» и для каждого из них перебирает свойство списка объектов «Desk» и извлекает поле «Id» в список.

Я придумал следующий код, используя потоки:

List<Long> deskIds = new ArrayList<>();
service.getAllNodesDepthFirst().stream().forEach(srv -> {
    deskIds.addAll(srv.getDesks().stream().map(Desk::getId).collect(Collectors.toList()));
});

Это правильный/оптимальный способ сделать это? Или есть способ сделать это без второго вложенного потока?


person Pierre Henry    schedule 27.11.2014    source источник
comment
Я думаю, что это нормально. С вашим подходом нет проблем.   -  person Prakhar Asthana    schedule 27.11.2014
comment
Для получения дополнительной информации перейдите по этой ссылке: oracle. com/technetwork/articles/java/   -  person Prakhar Asthana    schedule 27.11.2014
comment
@Prakhar: да, мой подход сработал, но он был немного наивен, и я подумал, что должен быть какой-то способ упростить его, как продемонстрировал assylias.   -  person Pierre Henry    schedule 27.11.2014


Ответы (1)


Я бы, наверное, написал так:

List<Long> deskIds = service.getAllNodesDepthFirst().stream()
                                          .flatMap(p -> p.getDesks().stream())
                                          .map(Desk::getId)
                                          .collect(toList());
person assylias    schedule 27.11.2014
comment
Да, я надеялся, что есть что-то вроде «flatMap»! - person Pierre Henry; 27.11.2014
comment
@assylias Есть ли какой-нибудь простой способ, если я хочу получить карту в конце вместо списка, где карта — это некоторый идентификатор ProvidedService, а значение — идентификатор стола. - person Naman; 29.09.2016
comment
@assylias Я посмотрел на groupingBy, но кажется, что я могу получить Map‹String, List‹String››, но я этого не хочу, я надеялся получить Map‹String, String› . Можете ли вы предложить, если я могу получить это? - person Naman; 30.09.2016
comment
Имеет смысл задать отдельный вопрос для вашего конкретного случая. - person assylias; 01.10.2016