【问题标题】:how to group items and convert to list in java如何在java中对项目进行分组并转换为列表
【发布时间】:2020-05-09 07:29:50
【问题描述】:

我有类似以下的 DTO

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;
    }
}

我有UserDTO 的列表,其中roleList 未填充,但role 已填充。问题是role 可能是多个但不知何故我无法设法在单个查询中获取列表。所以,我想按 id 分组并生成roleList

例如,我有以下几行:

id     fullName     phone     role     roleList
------------------------------------------------
abc    Sarwar       017xxx    admin    NULL
abc    Sarwar       017xxx    operator NULL

I want it to be like the following 

abc    Sarwar       017xxx    NULL      ArrayList<String>(admin, operator)

我尝试了以下方法,但它不起作用(不应该,但我不知道应该是什么)这就是我寻求您帮助的原因:

Map<String, List<UserDTO>> resultsWithSameIdAndName = users.stream()
        .collect(Collectors.groupingBy(r -> r.getId()));

List<UserDTO> mergedResults = resultsWithSameIdAndName.entrySet().stream()
        .map(e -> new UserDTO(e.getKey(), 
                e.getValue().stream().map(r -> r.getRole()).collect(Collectors.toList())))
        .collect(Collectors.toList());

提前致谢。

【问题讨论】:

  • 您的模型似乎存在设计问题。填充roleList 后,role 字段是什么意思?
  • 你能提到什么不起作用吗?对于您给出的示例,您的代码会产生什么输出?
  • @user7:实际上,这不是作为 DTO 的中间模型的实体。我无法从休眠中填充角色列表。实际上,我尝试过的代码没有填充角色列表。和以前一样是NULL。我希望它是List
  • 您在查看新的mergedResults 对象吗?还是users 对象?
  • @user7: mergedResults 实际上。实际上mergedResultsUserDTO 的列表,但mergedResults 不起作用。我想与id 分组并填充roleList。这是我的要求。谢谢。

标签: java list group-by dto


【解决方案1】:

您的代码应该可以工作。我为此添加了另一种方法。

首先由用户idroleList准备地图

Map<String, List<String>> resultsWithSameIdAndName = users.stream()
        .collect(Collectors.groupingBy(UserDTO::getId,
                 Collectors.mapping(d-> d.getRole(), Collectors.toList())));

然后按用户id创建唯一用户列表

List<UserDTO> uniqueUsers = users.stream()
    .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(UserDTO::getId))),ArrayList::new));

并从地图中获取角色列表并为每个用户设置

for(UserDTO user :uniqueUsers) {
    user.setRoleList(resultsWithSameIdAndName.get(user.getId()));
}

【讨论】:

  • 我发现这个错误 "The method toCollection(() -> {}) is undefined for the type UserDaoImpl"
  • 我更新了unique user list prepare part,现在检查,有问题是Comparator函数
  • 我还是发现了同样的错误……我想,可能是一些语法错误!! “toCollection(() -> {}) 的方法未定义”
  • 也许你没有静态导入toCollection。更新
  • 在这里我添加了完整的工作代码onlinegdb.com/BJOss-VqU,有趣的是你的代码也可以工作,我的代码也添加了
【解决方案2】:

这可能对你有用:

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

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

    public UserDTO(String id,String fullName,String phone,String role) {
        this.id = id;
        this.fullName = fullName;
        this.phone = phone;
        this.role =role;
    }

    public UserDTO(UserDTO oldObject,String key, List<String> collect) {
        this.id = key;
        this.fullName = oldObject.getFullName();
        this.phone = oldObject.getPhone();
        this.roleList = collect;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getFullName() {
        return fullName;
    }

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

    public String getPhone() {
        return phone;
    }

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

    public String getRole() {
        return role;
    }

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

    public List<String> getRoleList() {
        return roleList;
    }

    public void setRoleList(List<String> roleList) {
        this.roleList = roleList;
    }
    public static void main(String[] args) {

        ArrayList<UserDTO> list = new ArrayList<>();
        list.add(new UserDTO("ASD", "John", "12345", "user"));
        list.add(new UserDTO("ASD", "John", "12345", "admin"));
        list.add(new UserDTO("SDB", "Smith", "12345", "super user"));
        list.add(new UserDTO("SDB", "Smith", "12345", "admin"));
        list.add(new UserDTO("DFG", "Neo", "12345", "user"));
        Map<String, List<UserDTO>> resultsWithSameIdAndName = list.stream().collect(Collectors.groupingBy(UserDTO::getId));
        List<UserDTO> mergedResults = resultsWithSameIdAndName.entrySet().stream()
                .map(e -> new UserDTO(
                        e.getValue().get(0),
                        e.getKey(),
                        e.getValue().stream().map(UserDTO::getRole).collect(Collectors.toList())))
                .collect(Collectors.toList());
        System.out.println(mergedResults);

    }

}

我所做的唯一更改是在构造函数中添加一个参数,该参数采用UserDTO 对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    • 2015-02-23
    • 1970-01-01
    • 2021-08-01
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    相关资源
    最近更新 更多