简体   繁体   中英

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

I have two lists of custom objects. And I want to merge both lists by id , using Java 8.

I have a class Employee with the fields (All String): id , name , city .

And I have another class Person with the fields (All String): id , city .

Here is an example :

   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());

After merging the two lists I want to get the result shown below.

How can I do it?

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)
]

In order to achieve that, firstly, you can create two maps based on the two lists using id as a key .

Then create a stream over the key sets of these maps. Then inside the map() operation you need to create a new Employee object for every key by using passing a name extracted from the employeeList city taken from the personById .

When id is not present in either of the maps the object returned by get() will be null and attempt to invoke method on it will triger the NullPointerException . In order to handle this situation, we can make use of Null-object pattern, by defining two variables that could be safely accessed and will be provided as an argument to getOfDefault() .

Then collect the stream element into a list with 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);
}

Output

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

Not sure if Employee class here extends Person. Ideally, it should.

An Employee can be a Person, but not all Person has to be an Employee. So, collecting it as a List<Employee> makes no sense, due to this.

Ideally, you should collect it as a List<Person> and Employee should extend Person. Please relook at your class structure instead of focusing on collecting it as List<Employee> , that should solve your problem.

you can use mapping and grouping from stream or search the second list by id and update the employee to the first list. Java does not include built-in functions that will automatically merge different objects

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM