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
相关产品推荐
相关产品推荐

