Преобразование вложенного цикла for в поток, поддерживающий данные - PullRequest
0 голосов
/ 04 мая 2019

Я смотрю на код с глубоко вложенным циклом for, который я хотел переписать в чисто функциональной форме с использованием потоков java-8, но я вижу, что на каждом уровне необходимо несколько значений, и я не Уверен, как правильно решить эту проблему.

List<Report> reports = new ArrayList();
for (DigitalLogic dl : digitalLogics){
    for (Wizard wiz : dl.getWizards){
        for(Vice vice : wiz.getVices()){
           reports.add(createReport(dl, wiz, vice));
         }
    }
}

//
Report createReport(DigitalLogic dl, Wizard wiz, Vice vice){
  //Gets certain elements from all parameters and creates a report object
}

Мой реальный сценарий гораздо сложнее, чем этот, но мне интересно, есть ли более чистый и функциональный способ написания этого с использованием потоков. Ниже моя первая попытка

List<Report> reports = new ArrayList();
digitalLogics.stream()
.map(dl -> dl.getWizards())
.flatMap(List::stream())
.map(wiz -> wiz.getVices())
.flatMap(List::stream())
.forEach(vice -> reports.add(createReport(?, ?, vice));

Очевидно, я потерял ссылки на DigitalLogic и Wizard.

Ответы [ 2 ]

1 голос
/ 04 мая 2019

Я пойду с forEach методом, потому что stream решение усложняет

List<Report> reports = new ArrayList<>();
   digitalLogics.forEach(dl->dl.getWizards()
                .forEach(wiz->wiz.getVices()
                .forEach(v->reports.add(createReport(dl, wiz, v)))));
0 голосов
/ 04 мая 2019

Хотя в настоящее время то, что у вас есть (for петли), намного чище, чем то, что было бы с потоками, но если бы вы попробовали это:

public void createReports(List<DigitalLogic> digitalLogics) {
    List<Report> reports = digitalLogics.stream()
            .flatMap(dl -> dl.getWizards().stream()
                    .map(wizard -> new AbstractMap.SimpleEntry<>(dl, wizard)))
            .flatMap(entry -> entry.getValue().getVices().stream()
                    .map(vice -> createReport(entry.getKey(), entry.getValue(), vice)))
            .collect(Collectors.toList());
}
...