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

如何将List<Object>转为Map<String, List<Object>>并按元素属性去重?

解决List转Map<String, List>并去重的问题

嘿,这个需求用Java 8+的Stream API就能优雅搞定!结合你给出的RawItem和Item类,咱们分两步走:先对RawItem列表去重,再按category分组并转换为Item列表。

前提准备:给实体类添上必要方法

首先,RawItem和Item需要有构造器和getter方法(Stream要访问属性),如果要简化去重逻辑,还可以重写equals()和hashCode():

import java.util.Objects;

class RawItem {
    private String category;
    private int code;
    private String name;

    // 构造器
    public RawItem(String category, int code, String name) {
        this.category = category;
        this.code = code;
        this.name = name;
    }

    // Getter方法
    public String getCategory() { return category; }
    public int getCode() { return code; }
    public String getName() { return name; }

    // 可选:重写equals和hashCode,用于distinct()去重
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        RawItem rawItem = (RawItem) o;
        return code == rawItem.code &&
                Objects.equals(category, rawItem.category) &&
                Objects.equals(name, rawItem.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(category, code, name);
    }
}

class Item {
    private int code;
    private String name;

    public Item(int code, String name) {
        this.code = code;
        this.name = name;
    }

    // 可选:toString方便查看结果
    @Override
    public String toString() {
        return "Item{code=" + code + ", name='" + name + "'}";
    }
}

方案1:修改RawItem类,用distinct()去重(简洁版)

如果能修改RawItem的代码,重写equals()和hashCode()后,直接用distinct()就能轻松去重,再分组转换:

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

public class Main {
    public static void main(String[] args) {
        List<RawItem> rawItems = List.of(
            new RawItem("a", 1, "item1"),
            new RawItem("a", 1, "item1"),
            new RawItem("a", 2, "item2"),
            new RawItem("b", 1, "item1"),
            new RawItem("b", 1, "item1")
        );

        // 一步到位:去重 + 分组 + 转换
        Map<String, List<Item>> resultMap = rawItems.stream()
                .distinct() // 依赖重写的equals和hashCode去重
                .collect(Collectors.groupingBy(
                        RawItem::getCategory, // 按category作为Map的key
                        Collectors.mapping(
                                raw -> new Item(raw.getCode(), raw.getName()), // 转成Item
                                Collectors.toList()
                        )
                ));

        // 打印验证结果
        resultMap.forEach((cat, items) -> {
            System.out.println("分类:" + cat);
            items.forEach(System.out::println);
        });
    }
}

方案2:不修改RawItem类,用toMap去重(灵活版)

如果不能修改RawItem的源码,咱们可以用Collectors.toMap生成临时Map来实现去重,避免重写equals/hashCode:

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

public class Main {
    public static void main(String[] args) {
        List<RawItem> rawItems = List.of(
            new RawItem("a", 1, "item1"),
            new RawItem("a", 1, "item1"),
            new RawItem("a", 2, "item2"),
            new RawItem("b", 1, "item1"),
            new RawItem("b", 1, "item1")
        );

        // 第一步:去重——用category+code+name拼接成唯一key,重复时保留第一个元素
        List<RawItem> uniqueRawItems = rawItems.stream()
                .collect(Collectors.toMap(
                        // 生成唯一标识key:category_code_name
                        item -> item.getCategory() + "_" + item.getCode() + "_" + item.getName(),
                        item -> item, // value是原RawItem
                        (existing, newItem) -> existing // 重复key时保留已有元素
                ))
                .values() // 提取去重后的RawItem集合
                .stream()
                .collect(Collectors.toList());

        // 第二步:分组并转换为Item列表
        Map<String, List<Item>> resultMap = uniqueRawItems.stream()
                .collect(Collectors.groupingBy(
                        RawItem::getCategory,
                        Collectors.mapping(
                                raw -> new Item(raw.getCode(), raw.getName()),
                                Collectors.toList()
                        )
                ));

        // 打印结果
        resultMap.forEach((cat, items) -> {
            System.out.println("分类:" + cat);
            items.forEach(System.out::println);
        });
    }
}

结果验证

两种方案运行后都会输出:

分类:a
Item{code=1, name='item1'}
Item{code=2, name='item2'}
分类:b
Item{code=1, name='item1'}

完全符合你的需求:按category分组,每个分组里的Item没有重复项。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:21:54