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

如何用Java Streams按内部集合元素分组:将List<Shop>转为Map<Supplier, List<Shop>>

使用Java Streams实现从List<Shop>到Map<Supplier, List<Shop>>的转换

这是个典型的分组映射需求,核心思路是先扁平化每个店铺的供应商列表,再按供应商分组,我来一步步给你讲清楚实现细节:

1. 关键前提:重写Supplier的equals和hashCode

因为Supplier要作为Map的key,必须正确实现equals()和hashCode()方法——默认的对象引用比较会导致逻辑上完全相同的Supplier被当成不同的key,分组结果会出错。示例实现如下:

import java.util.Objects;

class Supplier {
    private Long id;
    private String supplierName;

    // 构造器、getter、setter方法省略

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

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

2. Streams完整实现代码

import java.util.List;
import java.util.Map;
import java.util.AbstractMap;
import java.util.stream.Collectors;
import java.util.Objects;

// 假设你已经初始化好了shops列表
List<Shop> shops = ...;

Map<Supplier, List<Shop>> supplierShopsMap = shops.stream()
    // 过滤掉供应商列表为null的店铺,避免空指针异常
    .filter(shop -> shop.getSuppliers() != null)
    // 扁平化处理:把每个店铺拆成「供应商-店铺」的键值对
    .flatMap(shop -> shop.getSuppliers().stream()
        // 可选:过滤掉null的供应商,让结果更干净
        .filter(Objects::nonNull)
        .map(supplier -> new AbstractMap.SimpleEntry<>(supplier, shop)))
    // 按供应商分组,收集对应的店铺列表
    .collect(Collectors.groupingBy(
        AbstractMap.SimpleEntry::getKey,
        Collectors.mapping(AbstractMap.SimpleEntry::getValue, Collectors.toList())
    ));

3. 代码分步解释

  • filter(shop -> shop.getSuppliers() != null):提前过滤掉供应商列表为null的店铺,防止后续调用stream()时抛出NPE。
  • flatMap(...):这是核心步骤,把单个Shop转换成多个(Supplier, Shop)键值对,让每个供应商都能和它所属的店铺建立关联。这里用AbstractMap.SimpleEntry临时存储键值对,不需要额外自定义类。
  • Collectors.groupingBy(...):
    • 第一个参数指定分组依据是Supplier(键值对中的key);
    • 第二个参数负责把键值对中的Shop收集成列表,作为对应Supplier的value。

可选优化

如果你的业务场景中不存在null的供应商或店铺,可以去掉对应的filter步骤,但保留null检查会让代码更健壮。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:27:15