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

Java中按多标识符分组对象列表的实现疑问

对象分组解决方案

核心思路

先按name与type的组合对对象进行一级分组,再在每个分组内按subType拆分出a和b的列表;之后将两个列表按索引配对,每一对a+b组成一个子列表,若某类数量超出另一类,剩余元素可按需处理(单独成列表或舍弃)。

实体类定义

假设我们的对象结构如下:

class Item {
    private String name;
    private String type;
    private String subType;

    public Item(String name, String type, String subType) {
        this.name = name;
        this.type = type;
        this.subType = subType;
    }

    // Getter方法
    public String getName() { return name; }
    public String getType() { return type; }
    public String getSubType() { return subType; }

    @Override
    public String toString() {
        return "Item{name='" + name + "', type='" + type + "', subType='" + subType + "'}";
    }
}

完整实现代码

import java.util.*;
import java.util.stream.Collectors;

public class ItemGrouping {
    public static void main(String[] args) {
        List<Item> items = Arrays.asList(
                new Item("A", "X", "a"),
                new Item("A", "X", "b"),
                new Item("A", "X", "a"),
                new Item("A", "X", "b"),
                new Item("A", "X", "a"),
                new Item("B", "Y", "a"),
                new Item("B", "Y", "b"),
                new Item("B", "Y", "b")
        );

        // 1. 按(name, type)分组,再按subType拆分a/b列表
        Map<List<String>, Map<String, List<Item>>> grouped = items.stream()
                .collect(Collectors.groupingBy(
                        item -> Arrays.asList(item.getName(), item.getType()),
                        Collectors.groupingBy(Item::getSubType)
                ));

        List<List<Item>> result = new ArrayList<>();
        // 2. 遍历每个(name, type)分组,配对a和b
        for (Map.Entry<List<String>, Map<String, List<Item>>> entry : grouped.entrySet()) {
            List<Item> aList = entry.getValue().getOrDefault("a", Collections.emptyList());
            List<Item> bList = entry.getValue().getOrDefault("b", Collections.emptyList());

            int maxCount = Math.max(aList.size(), bList.size());
            for (int i = 0; i < maxCount; i++) {
                List<Item> subList = new ArrayList<>();
                if (i < aList.size()) subList.add(aList.get(i));
                if (i < bList.size()) subList.add(bList.get(i));
                result.add(subList);
            }
        }

        // 打印结果
        result.forEach(sub -> {
            System.out.println("子列表:");
            sub.forEach(System.out::println);
            System.out.println("---");
        });
    }
}

代码说明

  • 分组阶段:通过嵌套的Collectors.groupingBy,先把同name+type的对象归为一组,再在组内拆分出subType=a和subType=b的两个列表,避免手动维护复杂的嵌套Map结构。
  • 配对阶段:遍历每个分组,按索引将a和b一一配对,生成符合要求的子列表。如果某类元素数量更多,剩余的元素会单独形成子列表;若只需要同时包含a和b的子列表,只需将maxCount替换为Math.min(aList.size(), bList.size())即可。

简化版(仅保留含a+b的子列表)

如果不需要单独的a或b子列表,仅保留同时包含a和b的组合,可修改配对逻辑:

int minCount = Math.min(aList.size(), bList.size());
for (int i = 0; i < minCount; i++) {
    result.add(Arrays.asList(aList.get(i), bList.get(i)));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 18:01:28