【问题标题】:Lambda merge inner object listLambda 合并内部对象列表
【发布时间】:2020-01-21 04:16:13
【问题描述】:

我正在尝试将empRegionList 合并为Emp,其中Emp 的列表具有相同的idfirstNamelastName,然后合并empRegionList,最终结果将是EmpEmpRegions 的列表,我得到了结果,但是有没有更好的方法来使用 Lambdas 来实现这一点。

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


class Emp{
    private String id;
    private String firstName;
    private String lastName;
    private List<EmpRegion> empRegionList;

    public Emp(String id, String firstName, String lastName, List<EmpRegion> empRegionList) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.empRegionList = empRegionList;
    }

    //get-set-equal-hashcode-toString methods
}

class EmpRegion{
    private String role;
    private String region;

    public EmpRegion(String role, String region) {
        this.role = role;
        this.region = region;
    }

    //get-set-equal-hashcode-toString methods
}
public class Test {
    public static void main(String[] args) {
        List<String> regions = Arrays.asList("USA", "UK", "INDIA","CHINA");
        Test t=new Test();
        Emp emp= t.getEmpWithMergedEmpRole("001",regions);
        System.out.println(emp);
    }
    private Emp getEmpWithMergedEmpRole(String id, List<String> regions){
            List<Emp> empList=new ArrayList<>();
            for(String region: regions){
                empList.add(getEmp(id,region));
            }
            List<EmpRegion> empRegionList= empList.stream().map(e -> e.getEmpRegionList()).flatMap(List::stream).collect(Collectors.toList());
            empList.get(0).setEmpRegionList(empRegionList);
            return empList.get(0);
    }
    private Emp getEmp(String id, String region) {
        return new Emp(id,"Abc","Def", Arrays.asList(new EmpRegion("RL-"+region, region)));
    }
}

【问题讨论】:

  • 实际上您的代码并没有按照您在问题中描述的那样做。根据我的假设,您希望根据 (id, firstName, lastName)Emp 进行分组。您的代码中缺少此分组...我已尝试使用输出来answer您的问题。可能这就是你要找的……
  • 谢谢 Mushif,你的回答很有帮助
  • 很高兴它对您有所帮助。

标签: java list lambda collections java-stream


【解决方案1】:

您可以将Collectors.toMapidfirstNamelastName 中的List 一起用作其键,并将Emp 作为其值,并使用合并函数将List&lt;EmpRegion&gt; 与@987654328 结合起来@ 具有相同键 (id, firstName, lastName) 的对象。之后,您可以通过将Mapvalues() 方法包装在ArrayList&lt;&gt;() 中来获得合并的List&lt;Emp&gt;

public static void main(String[] args) {
    Test t = new Test();

    // Dummy Values (with two different employees based on `id` = "001" & "002")
    List<Emp> employeeList = new ArrayList<>();
    employeeList.add(new Emp("001", "ABC", "DEF", t.getEmployeeRegionList("USA")));
    employeeList.add(new Emp("001", "ABC", "DEF", t.getEmployeeRegionList("UK")));
    employeeList.add(new Emp("001", "ABC", "DEF", t.getEmployeeRegionList("INDIA")));
    employeeList.add(new Emp("001", "ABC", "DEF", t.getEmployeeRegionList("CHINA")));
    employeeList.add(new Emp("002", "ABC", "DEF", t.getEmployeeRegionList("CHINA", "RUSSIA")));
    employeeList.add(new Emp("002", "ABC", "DEF", t.getEmployeeRegionList("USA")));

    System.out.println(t.getEmployeesWithMergedEmpRoles(employeeList));
}

private List<Emp> getEmployeesWithMergedEmpRoles(List<Emp> employeeList) {
    return new ArrayList<>(employeeList.stream().collect(Collectors.toMap(emp -> Arrays.asList(emp.getId(), emp.getFirstName(), emp.getLastName()), 
            Function.identity(), (oldValue, newValue) -> {
        oldValue.getEmpRegionList().addAll(newValue.getEmpRegionList());
        return oldValue;
    })).values());
}

private List<EmpRegion> getEmployeeRegionList(String... regions) {
    List<EmpRegion> empRegionList = new ArrayList<>();
    for (String region : regions) {
        empRegionList.add(new EmpRegion("RL-" + region, region));
    }
    return empRegionList;
}

输出:

[
  Emp(id="001", firstName="ABC", lastName="DEF",
  empRegionList=[
    EmpRegion(role="RL-USA", region="USA"),
    EmpRegion(role="RL-UK", region="UK"),
    EmpRegion(role="RL-INDIA", region="INDIA"),
    EmpRegion(role="RL-CHINA", region="CHINA")
  ]),

  Emp(id="002", firstName="ABC", lastName="DEF",
  empRegionList=[
    EmpRegion(role="RL-CHINA", region="CHINA"),
    EmpRegion(role="RL-RUSSIA", region="RUSSIA"),
    EmpRegion(role="RL-USA", region="USA")
  ])
] 

【讨论】:

    【解决方案2】:
    public class Test{
    
         public static void main(String[] args) {
                List<String> regions = Arrays.asList("USA", "UK", "INDIA","CHINA");
                Test t=new Test();
                Emp emp= t.getEmpWithMergedEmpRole("001",regions);
                System.out.println(emp);
            }
            private Emp getEmpWithMergedEmpRole(String id, List<String> regions){
                    List<EmpRegion> empRegionList = regions.stream().map(region -> new EmpRegion("RL-"+region, region)).collect(Collectors.toList());
                    return new Emp(id,"Abc","Def", empRegionList);
            }
    }
    

    【讨论】:

      【解决方案3】:
      private Emp getEmpWithMergedEmpRole(String id, List<String> regions) {
          List<Emp> empList = new ArrayList<>();
          for (String region : regions) {
              empList.add(getEmp(id, region));
          }
          Emp emp = empList.get(0);
          empList.stream()
                  .map(Emp::getEmpRegionList)
                  .forEach(emp.getEmpRegionList()::addAll);
          return emp;
      }
      
      private Emp getEmp(String id, String region) {
          return new Emp(id, "Abc", "Def", new ArrayList<>(Arrays.asList(new EmpRegion("RL-" + region, region))));
      }
      

      但需要此变体:new ArrayList&lt;&gt;(Arrays.asList(new EmpRegion(...)))

      【讨论】:

        猜你喜欢
        • 2023-03-06
        • 2014-03-19
        • 2017-09-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-23
        • 2019-12-07
        相关资源
        最近更新 更多