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

如何使用Stream的groupingBy方法按嵌套对象C.id分组List<A>

用Java Stream groupingBy实现按C对象分组List

嘿,这个需求很常见,我来给你拆解一下怎么用Java Stream的groupingBy搞定它。

首先得明确你的对象层级:A包含B,B包含C,所以每个A实例都能通过A.getB().getC()拿到对应的C对象。我们要把List<A>按C分组为Map<C, List<A>>,核心其实就两步:

1. 确保C类正确实现equals()和hashCode()

这一步非常关键!因为groupingBy默认使用HashMap来存储分组结果,而HashMap是通过equals()和hashCode()来判断两个C对象是否相等的。如果你的分组逻辑是基于C.id(也就是id相同的C就算同一个分组key),那你的C类必须基于id来实现这两个方法:

import java.util.Objects;

class C {
    private Long id;
    // 其他字段、getter、setter

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        C c = (C) o;
        return Objects.equals(id, c.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}

如果不做这一步,哪怕两个C对象的id相同,只要是不同的实例,HashMap都会把它们当成不同的key,分组结果就会出错。

2. 用Stream的groupingBy完成分组

这一步就很直接了,调用stream()后,用Collectors.groupingBy()传入提取C对象的lambda表达式即可:

List<A> listOfA = ...; // 你的A集合实例

Map<C, List<A>> groupedMap = listOfA.stream()
    .collect(Collectors.groupingBy(a -> a.getB().getC()));

额外处理:避免空指针异常

如果你的业务场景中,A的B或者B的C可能为null,那上面的代码会抛出NullPointerException。这时候你可以先过滤掉这些无效元素:

Map<C, List<A>> groupedMap = listOfA.stream()
    // 过滤掉B或C为null的A实例
    .filter(a -> a.getB() != null && a.getB().getC() != null)
    .collect(Collectors.groupingBy(a -> a.getB().getC()));

如果需要保留这些包含null的元素,可以把它们分到null对应的key下(不过这种场景要根据业务需求来判断是否合理):

Map<C, List<A>> groupedMap = listOfA.stream()
    .collect(Collectors.groupingBy(a -> {
        if (a.getB() == null || a.getB().getC() == null) {
            return null;
        }
        return a.getB().getC();
    }));

总结一下

  • 核心就是Collectors.groupingBy(a -> a.getB().getC()),但前提是C类的equals()和hashCode()要符合你的分组逻辑。
  • 一定要考虑空值情况,避免运行时异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:58:46