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

如何用Java8 Stream将Model列表按Property名称分组为指定Map

用Java 8 Stream实现按Property名称分组的方案

当然可以用单条Java 8 Stream完成这个需求,不需要拆分或者退回到传统循环写法,而且代码简洁易读。

核心思路

因为每个Model包含多个Property,我们需要先把每个Model和它的每个Property做一对多的展开,生成(Property名称, Model)的键值对,再按Property名称分组,最后把同组的Model收集到Set中。

完整实现代码

List<Model> models = ...; // 你的Model列表

Map<String, Set<Model>> propertyToModelsMap = models.stream()
    // 把每个Model展开成多个(Property名称, Model)的键值对
    .flatMap(model -> model.getProperties().stream()
        .map(property -> new AbstractMap.SimpleEntry<>(property.getName(), model)))
    // 按Property名称分组,同时将每个分组的Model收集为Set
    .collect(Collectors.groupingBy(
        Map.Entry::getKey,
        Collectors.mapping(Map.Entry::getValue, Collectors.toSet())
    ));

代码逐行解释

  1. flatMap阶段:

    • 遍历每个Model,再遍历它的properties列表,把每个Property转换成AbstractMap.SimpleEntry(一种简单的键值对实现),键是Property的name,值是当前Model。
    • flatMap会把所有这些键值对合并成一个连续的流,代替嵌套的流结构。
  2. collect阶段:

    • Collectors.groupingBy(Map.Entry::getKey):按键值对的key(也就是Property的名称)进行分组。
    • 第二个参数Collectors.mapping(Map.Entry::getValue, Collectors.toSet()):把每个分组里的Model(也就是键值对的value)收集到Set中,最终得到Map<String, Set<Model>>。

补充说明

虽然题目提到“所有Property的名称都是唯一的”,意味着每个键对应的Set里只会有一个Model,但用Set依然符合需求。如果想直接得到Map<String, Model>,可以改用Collectors.toMap(合并函数不会触发,因为名称唯一):

Map<String, Model> propertyToModelMap = models.stream()
    .flatMap(model -> model.getProperties().stream()
        .map(p -> new AbstractMap.SimpleEntry<>(p.getName(), model)))
    .collect(Collectors.toMap(
        Map.Entry::getKey,
        Map.Entry::getValue,
        (existing, newModel) -> existing // 名称唯一,该逻辑不会执行
    ));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:09:41