Comparator.comparing(…).thenComparing(…) find out which fields did not match

Tags: , ,



I am trying to compare two objects of same class and the goal is to compare them as well as identify which fields didn’t match.

Example of my domain class

@Builder(toBuilder=true)
class Employee {
     String name;
     int age;
     boolean fullTimeEmployee;
}

Two objects

Employee emp1 = Employee.builder().name("john").age(25).fullTime(false).build();
Employee emp2 = Employee.builder().name("Doe").age(25).fullTime(true).build();

Comparing both objects

int result = Comparator.comparing(Employee::getName, Comparator.nullsFirst(Comparator.naturalOrder()))
                       .thenComparing(Employee::getAge, Comparator.nullsFirst(Comparator.naturalOrder()))
                       .thenComparing(Employee::isFullTimeEmployee, Comparator.nullsFirst(Comparator.naturalOrder()))
                       .compare(emp1, emp2);

result will be 0 because name & fullTime fields are not matching with each other.

But I also want to produce a list of fields which didn’t match.. like below

List<String> unmatchedFields = ["name","fulltimeEmployee"];

Can I do it in a nicer way, other than bunch of if() else

Answer

Check out DiffBuilder. It can report which items are different.

DiffResult<Employee> diff = new DiffBuilder(emp1, emp2, ToStringStyle.SHORT_PREFIX_STYLE)
       .append("name", emp1.getName(), emp2.getName())
       .append("age", emp1.getAge(), emp2.getAge())
       .append("fulltime", emp1.getFulltime(), emp2.getFulltime())
       .build();

DiffResult has, among other things, a getDiffs() method that you can loop over to find what differs.



Source: stackoverflow