【问题标题】:Optimum way to merge elements in an ArrayList in java在java中合并ArrayList中元素的最佳方法
【发布时间】:2020-11-06 21:46:53
【问题描述】:

我有一个List<QueryResult>,其中QueryResult 的结构如下-

class QueryResult{
    int projectId;
    int taskId;
    String projectName;
    String projectManager;
}
    

现在我为 QueryResult 得到的结果是这样的:

queryResult1 -> {projectId:1, taskId:**21**, projectName="xyz" projectManager="abc"}
queryResult1 -> {projectId:1, taskId:**22**, projectName="xyz" projectManager="abc"}
queryResult1 -> {projectId:1, taskId:**23**, projectName="xyz" projectManager="abc"}
queryResult1 -> {projectId:2, taskId:31, projectName="prj2" projectManager="dc"}
queryResult1 -> {projectId:2, taskId:41, projectName="prj2" projectManager="dc"}

现在我想要的输出是这样的:

DesiredOutput -> 
  {projectId:1,taskIds:{21,22,23}, projectName="xyz" projectManager="abc"}
  {projectId:2,taskIds:{31,41}, projectName="prj2" projectManager="dc"}

所以我想将多行转换为一对一projectId 并将不同的taskIds 合并在一起。对于特定项目 ID,除 taskId 之外的其他详细信息保持不变。

我是 java 8 的新手,想以函数式的方式来做这件事。我的解决方案是流式传输所有 queryResults 对象,然后创建一个Map<ProjectID, List<TaskIds>>,但不确定如何以功能样式获取它,并且还必须合并我的结果以形成结果输出。 我正在寻找解决这个小问题的最佳方法。

【问题讨论】:

  • 您可能正在寻找Collectors.groupingBy(QueryResult::getProjectId),然后将其映射到您的DesiredOutput 对象

标签: java arraylist collections java-8


【解决方案1】:
class QueryResultTransformed{
    int projectId;
    List<Integer> taskId;
    String projectName;
    String projectManager;
    }
List<QueryResultTransformed> result = queryResults.stream()
                                    .collect(groupingBy(QueryResult::getProjectId))
                                    .entrySet()
                                    .stream()
                                    .map(e->{
                                    QueryResultTransformed obj = new QueryResultTransformed();
                                    List<QueryResult> list= e.getValue()
                                    List<Integer> taskIds = list.stream().map(QueryResult::getTaskId).collect(Collectors.toList());
                                    obj.setProjectId(e.getKey());
                                    obj.setProjectName(list.get(0).getProjectName());
                                    obj.setProjectManager(list.get(0).getProjectManager());
                                    obj.setTaskIds(taskIds);
                                    return obj;
                                  }).collect(Collectors.toList());

                

【讨论】:

    【解决方案2】:

    一个示例代码用于演示,包括为最终预期结果创建一个新容器类,我使用record 来避免这种特殊情况的样板。

    record QueryResultTasks(int projectId, String projectName,
                            String projectManager, List<Integer> taskIds) {
    }
    

    然后您可以迭代查询结果并创建一个中间映射用于投影到 taskId 分组

    Map<Integer, List<Integer>> taskGrouping = queryResults.stream()
            .collect(Collectors.groupingBy(QueryResult::getProjectId,
                    Collectors.mapping(QueryResult::getTaskId, Collectors.toList())));
    

    此外,初始列表和中间映射可用于使用map 操作获得所需的结果

    List<QueryResultTasks> resultTasks = queryResults.stream()
            .map(qr -> new QueryResultTasks(qr.getProjectId(), qr.getProjectName(),
                    qr.getProjectManager(), taskGrouping.get(qr.getProjectId())))
            .collect(Collectors.toList());
    

    【讨论】:

      猜你喜欢
      • 2021-12-31
      • 1970-01-01
      • 1970-01-01
      • 2010-10-14
      • 1970-01-01
      • 1970-01-01
      • 2010-11-02
      • 1970-01-01
      • 2016-09-11
      相关资源
      最近更新 更多