如何使用 Java 合并两个不同类型的自定义对象列表 8

How can I Merge two Lists of custom objects of a Different Type using Java 8

我有两个 列表 自定义对象。我想通过 id 合并两个 lists,使用 Java 8.

我有一个 class Employee 字段(所有字符串):idnamecity.

我还有另一个 class Person 字段(所有字符串):idcity.

这是一个例子 :

   List<Employee> employeeList = Stream.of(
                        new Employee("100","Alex",""),
                        new Employee("200","Rida",""),
                        new Employee("300","Ganga",""))
                .collect(Collectors.toList());

        List<Person> personList = Stream.of(
                        new Person("100","Atlanta"),
                        new Person("300","Boston"),
                        new Person("400","Pleasanton"))
                .collect(Collectors.toList());

合并两个列表后,我想得到如下所示的结果。

我该怎么做?

List<Employee> 
[
Employee(id=100, name=Alex, city=Atlanta), 
Employee(id=200, name=Rida, city=null), 
Employee(id=300, name=Ganga, city=Boston),
Employee(id=400, name=null, city=Pleasanton)
]

您可以使用流中的映射和分组,或按 ID 搜索第二个列表并将员工更新到第一个列表。 Java不包括built-in会自动合并不同对象的功能

为了实现这一点,首先,您可以使用 id 基于两个列表创建两个 maps 作为一个.

然后在这些地图的 键集 上创建流。然后在 map() 操作中,您需要通过传递从 employeeList city 中提取的 name 为每个键创建一个新的 Employee 对象 city =18=].

id 不存在于任一 映射中时 get() 返回的对象将是 null 并尝试调用方法它将触发 NullPointerException。为了处理这种情况,我们可以利用Null-object模式,通过定义两个可以安全访问的变量作为 getOfDefault().

的参数提供

然后用Collectors.toList().

将流元素收集到列表中
public static void main(String[] args) {
    List<Employee> employeeList = Stream.of(
                    new Employee("100","Alex",""),
                    new Employee("200","Rida",""),
                    new Employee("300","Ganga",""))
            .collect(Collectors.toList());

    List<Person> personList = Stream.of(
                    new Person("100","Atlanta"),
                    new Person("300","Boston"),
                    new Person("400","Pleasanton"))
            .collect(Collectors.toList());

    Map<String, Employee> employeeById = employeeList.stream()
            .collect(Collectors.toMap(Employee::getId, Function.identity()));

    Map<String, Person> personById = personList.stream()
            .collect(Collectors.toMap(Person::getId, Function.identity()));

    Person nullPerson = new Person("", null);             // null-object
    Employee nullEmployee = new Employee("", null, null); // null-object

    List<Employee> result = Stream.concat(employeeById.keySet().stream(),
                                          personById.keySet().stream())
            .distinct() // eliminating duplicated keys
            .map(key -> new Employee(key,
                    employeeById.getOrDefault(key, nullEmployee).getName(),
                    personById.getOrDefault(key, nullPerson).getCity()))
            .collect(Collectors.toList());
    
    result.forEach(System.out::println);
}

输出

Employee{id='100', name='Alex', city='Atlanta'}
Employee{id='200', name='Rida', city='null'}
Employee{id='300', name='Ganga', city='Boston'}
Employee{id='400', name='null', city='Pleasanton'}

不确定此处的 Employee class 是否扩展了 Person。理想情况下,它应该。

Employee 可以是Person,但不是所有Person 都必须是Employee。因此,将其收集为 List<Employee> 没有任何意义,因此。

理想情况下,您应该将其收集为 List<Person> 并且 Employee 应该扩展 Person。请重新查看您的 class 结构,而不是专注于将其收集为 List<Employee>,这应该可以解决您的问题。