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

Java中按ID分组UserDTO并生成roleList的实现方案

解决UserDTO多角色合并问题

你遇到的问题是现有代码只初始化了id和roleList,完全忽略了fullName、phone这些字段的赋值,也没把role字段设为null,所以才达不到预期效果。咱们一步步来修正:

第一步:调整UserDTO(必要前提)

你的UserDTO目前只有一个接收id和roleList的构造函数,而且其他字段没有setter方法,没法设置fullName、phone和role。所以需要先做一下调整,二选一即可:

方案A:添加全参构造函数

修改UserDTO,新增包含所有字段的构造函数:

public class UserDTO implements Serializable {
    private String id;
    private String fullName;
    private String phone;
    private String role;
    private List<String> roleList;

    // 原构造函数保留
    public UserDTO(String id, List<String> roleList) {
        super();
        this.id = id;
        this.roleList = roleList;
    }

    // 新增全参构造函数
    public UserDTO(String id, String fullName, String phone, String role, List<String> roleList) {
        this.id = id;
        this.fullName = fullName;
        this.phone = phone;
        this.role = role;
        this.roleList = roleList;
    }

    // 别忘了添加getter方法(你应该已经有了,否则stream里的getRole()等方法没法用)
    public String getId() { return id; }
    public String getFullName() { return fullName; }
    public String getPhone() { return phone; }
    public String getRole() { return role; }
}

方案B:添加setter方法

如果不想新增构造函数,给每个字段添加setter:

public class UserDTO implements Serializable {
    // ... 原有字段和构造函数不变

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public void setRole(String role) {
        this.role = role;
    }

    // 原有getter方法保留
}

第二步:编写合并逻辑

根据你选择的UserDTO调整方案,对应两种实现方式:

方式A:用全参构造函数实现

Map<String, List<UserDTO>> groupedById = users.stream()
    .collect(Collectors.groupingBy(UserDTO::getId));

List<UserDTO> mergedResults = groupedById.values().stream()
    .map(group -> {
        // 取分组中第一个元素的基础信息(假设同id的fullName、phone都是一致的)
        UserDTO firstUser = group.get(0);
        // 收集该分组下所有的role到roleList
        List<String> roles = group.stream()
            .map(UserDTO::getRole)
            .collect(Collectors.toList());
        // 创建合并后的UserDTO,role设为null,其他字段沿用第一个元素的值
        return new UserDTO(
            firstUser.getId(),
            firstUser.getFullName(),
            firstUser.getPhone(),
            null,
            roles
        );
    })
    .collect(Collectors.toList());

方式B:用setter方法实现

Map<String, List<UserDTO>> groupedById = users.stream()
    .collect(Collectors.groupingBy(UserDTO::getId));

List<UserDTO> mergedResults = groupedById.values().stream()
    .map(group -> {
        UserDTO firstUser = group.get(0);
        List<String> roles = group.stream()
            .map(UserDTO::getRole)
            .collect(Collectors.toList());
        // 用原有构造函数创建对象,再通过setter补充其他字段
        UserDTO mergedUser = new UserDTO(firstUser.getId(), roles);
        mergedUser.setFullName(firstUser.getFullName());
        mergedUser.setPhone(firstUser.getPhone());
        mergedUser.setRole(null);
        return mergedUser;
    })
    .collect(Collectors.toList());

关键说明

  • 这里假设同一id的UserDTO的fullName和phone字段值完全一致,这符合你给出的示例数据场景;如果存在不一致的情况,你需要额外处理(比如取第一个、取最常见值等)。
  • 合并后的role字段被设置为null,完全匹配你期望的输出结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 16:37:59