comparing two instances of random java class to obtain differences of variables values

77 Views Asked by At

I need to compare two instances of the same java class and obtain the list of variables that are not equals.

Let's say i have this kind of java class

public class DummyClass
{
    private String name;
    private String surname;
    [constructors, getters and setters ...]
}

At runtime I have 2 instances of DummyClass, let's say a = ["foo", "bar"] and b = ["foo", "rab"], so with same names but different surnames. My goal is to compare them and hilight the fact that a.surname is not equals to b.surname, and also give as output something that sounds more or less like "field not equals: surname, values found a.surname = 'bar' - b.surname = 'rab'" I have too many classes, can't override the compareTo into each one of them, so as first approach i randomly landed on xmlunit --> great! perfect! it offer exactly what I need IF I start from two xml files, so I tought to use JAXB for the mapping class - to - xml but with Java 17 I can't use JAXB, and I can't switch to previous version of Java.

Is there any workaround to do what XMLUNIT does? XML approach was just an idea, i can use whatever does the job.

2

There are 2 best solutions below

0
WJS On

I can use whatever does the job.

Here is one way using just Java.

  • declare a BiFunction to check the two instances. (A regular method could also work).
  • Then call the function to validate the two. An empty string is returned on success.
BiFunction<DummyClass, DummyClass, String> checkNames = (d1, d2) -> {
     if (!d1.getName().equals(d2.getName())) {
         return "fields not equal: name, values found a.name = '%s' - b.name = '%s'"
                 .formatted(d1.getName(), d2.getName());
     } else if (!d1.getSurname().equals(d2.getSurname())) {
         return "fields not equal: surname, values found a.surname = '%s' - b.surname = '%s'"
                 .formatted(d1.getSurname(), d2.getSurname());
     } else {
         return "";
     }
};

Create some instances to evaluate.

DummyClass dc1 = new DummyClass("foo", "bar");
DummyClass dc2 = new DummyClass("foo", "rab");
DummyClass dc3 = new DummyClass("oof", "bar");

String result = checkNames.apply(dc1, dc2);
if (!result.isEmpty()) {
     System.out.println(result);
}

result = checkNames.apply(dc2, dc3);
if (!result.isEmpty()) {
     System.out.println(result);
}

prints

fields not equal: surname, values found a.surname = 'bar' - b.surname = 'rab'
fields not equal: name, values found a.name = 'foo' - b.name = 'oof'
0
Antonio On

Ok seems I read just the half of the story ... JAXB was removed since JAVA 11, but using JAXB reference implementation in conjunction with jakarta still does the trick.

I solved adding this to the pom and using the two above mentioned.

<dependencies>
    <dependency>
        <groupId>jakarta.xml.bind</groupId>
        <artifactId>jakarta.xml.bind-api</artifactId>
        <version>4.0.0</version>
    </dependency>
 <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>4.0.2</version>
        <scope>runtime</scope>
    </dependency>
</dependencies>