将嵌套的for循环转换为维护数据的流

时间:2019-05-04 02:13:44

标签: java java-8 functional-programming java-stream

我正在查看一个深深嵌套于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 个答案:

答案 0 :(得分:1)

我将使用forEach方法,因为stream解决方案使这一过程变得复杂

List<Report> reports = new ArrayList<>();
   digitalLogics.forEach(dl->dl.getWizards()
                .forEach(wiz->wiz.getVices()
                .forEach(v->reports.add(createReport(dl, wiz, v)))));

答案 1 :(得分:0)

尽管目前拥有的内容(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());
}