【问题标题】:Refactor creation of a list with java 8 streams使用 java 8 流重构列表的创建
【发布时间】:2016-07-12 04:54:34
【问题描述】:

我找到了以下代码,它在某些情况下(如果它不是旧的)将一个项目添加到列表中。之后这个列表会被打包到一个通用的控件列表中。

    List<ListDataContent> list = new ArrayList<>();

    for (KonditionValue kondition : konditions) {
        if (kondition.getStatusKz().equals(StatusKz.OLD))
            continue;
        for (TermKondValue tilg : kondition.getTermimKonditions()) {
            if (tilg.getStatusKz().equals(StatusKz.OLD))
                continue;

            TerminKondListContent listContent = new TerminKondListContent(tilg, kondition.getChangeDatum(), funds);
            list.add(listContent);
        }
    }

    SimpleListControl listCtrl = new SimpleListControl();
    listCtrl.setDataModel(new ListDataModel(list));

我尝试使用 java8 流进行以下重构:

List<ListDataContent> list = konditionen.stream().map(kondition -> map(tilg, kondition.getChangeDate(), funds)).sorted().collect(Collectors.toList());
SimpleListControl listCtrl = new SimpleListControl();
listCtrl.setDataModel(new ListDataModel(list));

问题出在map方法上……

private TerminKondListContent map(TermKondValue tilg, Date changeDate, BigDecimal funds) {
    if (kondition.getStatusKz().equals(StatusKz.OLD))
        return null;
    for (TermKondValue zins : kondition.getTerminkonditions()) {
        if (zins.getStatusKz().equals(StatusKz.OLD))
            return null;

        return new TerminKondListContent(tilg, changeDate, funds);
    }
    return null;
}

在继续的情况下我可以做什么?返回空?然后我可以通过

从流中过滤空值
list.stream().filter( Objects::nonNull )

这里可以选择使用 Optionals 吗?

【问题讨论】:

    标签: java java-8 refactoring java-stream


    【解决方案1】:

    不是很漂亮,但你可以拥有以下

    List<ListDataContent> list = 
        konditions.stream()
                  .filter(kondition -> !kondition.getStatusKz().equals(StatusKz.OLD))
                  .flatMap(kondition -> 
                     kondition.getTerminTilgkonditions()
                              .stream()
                              .filter(tilg -> !tilg.getStatusKz().equals(StatusKz.OLD))
                              .map(tilg -> new AbstractMap.SimpleEntry<>(kondition, tilg))
                  )
                  .map(e -> new TerminKondTilgListContent(e.getValue(), e.getKey().getChangeDatum(), funds))
                  .collect(Collectors.toList());
    

    这会创建一个Stream&lt;KonditionValue&gt;,并且只保留状态不是StatusKz.OLD 的那些。然后,它将它们中的每一个平面映射到它们的 TermKondTilgValues 中,其中只保留状态不是 StatusKz.OLDTermKondTilgValue

    请注意,我们保留了对TermKondTilgValueKonditionValue 的引用,因为我们以后需要,所以我们使用AbstractMap.SimpleEntry 作为两个值的持有者。

    最后将此Stream映射到对应的TerminKondTilgListContent,并收集到一个列表中。

    【讨论】:

    • 这应该可以。你不觉得读起来有点难吗?我的解决方案看起来更具可读性。虽然我仍然不确定在这种情况下如何处理“return null”。
    • @Chris311 您的解决方案实际上是旧代码的混合。我确实认为它有点难以阅读,因此保留你的 for 循环并不是一个坏主意。
    • 好的,我不会在这里使用 java8 流重构 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    • 2021-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多