You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Java 8 Streams API替换嵌套三重循环赋值逻辑

如何用Java 8 Streams API替代嵌套三重循环为对象属性赋值

我现在要处理三个列表,通过嵌套三重循环根据匹配条件给对象属性赋值。作为Java新手,想知道怎么用Java 8 Streams API替换下面的嵌套循环逻辑,求指导。

类定义

class B {
    Long id;
    Long x;
    String y;
    Long z;
    // 假设已生成getter和setter方法
}

class A {
    private Long id;
    private List<B> bList;
    // 假设已生成getter方法
}

class C {
    private Long id;
    private List<Long> bIds;
    private String y;
    private Long z;
    // 假设已生成getter方法
}

待替换的嵌套三重循环

void f(List<A> aList, List<C> cList) {
    for(A a : aList) {
        List<B> bList= a.getBList();
        for(B b : bList) {
            for(C c : cList) {
                if(a.getId().equals(c.getId()) && c.getBIds().contains(b.getId())) {
                    b.setZ(c.getZ());
                    b.setY(c.getY());
                }
            }
        }
    }
}

用Streams API实现的方案

第一步:预处理C列表,构建高效查找映射

原循环中c.getBIds().contains(b.getId())是线性查找,效率较低。先把cList转换成嵌套Map,外层key为A/C的id,内层key为B的id,后续查找可达到O(1)时间复杂度:

Map<Long, Map<Long, C>> cMapping = cList.stream()
    .collect(Collectors.toMap(
        C::getId,
        c -> c.getBIds().stream()
            .collect(Collectors.toMap(
                bid -> bid,
                bid -> c
            ))
    ));

第二步:用Streams遍历赋值

通过flatMap展开所有B对象,再通过预处理的映射找到匹配的C,完成属性赋值:

void fWithStreams(List<A> aList, List<C> cList) {
    // 构建查找映射
    Map<Long, Map<Long, C>> cMapping = cList.stream()
        .collect(Collectors.toMap(
            C::getId,
            c -> c.getBIds().stream()
                .collect(Collectors.toMap(
                    bid -> bid,
                    bid -> c
                ))
        ));

    // 遍历并赋值
    aList.stream()
        .flatMap(a -> a.getBList().stream()
            .peek(b -> {
                Map<Long, C> bIdToC = cMapping.get(a.getId());
                if (bIdToC != null) {
                    C matchedC = bIdToC.get(b.getId());
                    if (matchedC != null) {
                        b.setY(matchedC.getY());
                        b.setZ(matchedC.getZ());
                    }
                }
            })
        )
        .forEach(b -> {}); // 终端操作触发流执行,也可用count()替代
}

逻辑说明

  1. 预处理映射大幅降低了原循环的时间复杂度,避免重复遍历查找
  2. flatMap将每个A的bList展开为单个B的流,统一处理
  3. peek用于在流处理过程中修改B的属性,需配合终端操作(如forEach)触发执行
  4. 该实现和原嵌套循环的逻辑完全一致:若一个B匹配多个C,最后匹配的C会覆盖属性值

内容的提问来源于stack exchange,提问作者Sandeep Barnabas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 12:48:26