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

Time:04-06

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

CodePudding user response:

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.

CodePudding user response:

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

CodePudding user response:

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

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

Map<String, Person> personById = employeeList.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.of(employeeById.keySet().stream(), 
                                  personById.keySet().stream())
        .map(key -> new Employee(key, 
                    employeeById.getOrDefault(key, nullEmployee).getName(), 
                    personById.getOrDefault(key, nullPerson).getCity()))
        .collect(Collectors.toList()); // or .toList() for Java 16 
  • Related