How to compare two objects and find changed fields / properties?

I need to write some general solution to find out which properties in two objects have changed and return the changed properties (not the value).

class Student {
    public String name;
    public Address address;
    public int age;
}

class Address {
    public String hno;
    public String street;
    public int pin;
}

public class Test {
    public static void main(String... arg) {

        Student s1 = new Student();
        s1.name = "Krishna";
        s1.age = 30;
        s1.address = new Address();
        s1.address.hno = "2-2-22";
        s1.address.street = "somewhere";
        s1.address.pin = 123;

        Student s2 = new Student();
        s2.name = "Krishna";
        s2.age = 20;
        s2.address = new Address();
        s2.address.hno = "1-1-11";
        s2.address.street = "nowhere";
        s2.address.pin = 123;

        List<String> = difference(s1, s2);
        // expected result
        // Student.age
        // Student.address.hno
        // Student.address.street
    }
}

Can someone suggest some solution?

PS

Overriding equals / hashcode is not an option for me.

I wrote the code below, but I'm not sure how to determine if the type is complex (e.g. Address)

private static List<String> difference(Student s1, Student s2) throws IllegalArgumentException, IllegalAccessException {

        for(Field field: Student.class.getDeclaredFields()) {
            System.out.println(field.getName() + " " +field.get(s1).equals(field.get(s2)));
        }
        return null;
    }
+4
source share
4 answers

I think this is the method you are looking for:

 private static List<String> difference(Student s1, Student s2) throws IllegalAccessException {
     List<String> changedProperties = new ArrayList<>();
     for (Field field : s1.getClass().getDeclaredFields()) {
        // You might want to set modifier to public first (if it is not public yet)
        field.setAccessible(true);
        Object value1 = field.get(s1);
        Object value2 = field.get(s2); 
        if (value1 != null && value2 != null) {
            System.out.println(field.getName() + "=" + value1);
            System.out.println(field.getName() + "=" + value2);
            if (!Objects.equals(value1, value2)) {
                changedProperties.add(field.getName());
            }
        }
    }
    return changedProperties;
 }
+1
source

Although this is an old question, I would like to add an idea: -

  1. Use JAXB to convert Java objects to XML.
  2. Use XMLUnit to compare differences in XML.

, , ..

, , XML; . , ( ) .

+1

, .

 public boolean difference(student s1,Student s2) throws IllegalArgumentException, IllegalAccessException {

     for (Field f : s1.getClass().getDeclaredFields()) {
         for (Field g: s2.getClass().getDeclaredFields()) {
             write your logic by comparing your specify fields  -- 
             g.getname().equalsIgnoreCase(f.getName())
         }
     }
     return the true or false 
 }
0

1. , :

//Add this in Student Class
public static List<String> difference(Student s1, Student s2) {
    List<String> res = new ArrayList<>();
    if (!s1.name.equalsIgnoreCase(s2.name)) res.add("name");
    if (s1.age != s2.age) res.add("age");
    res.addAll(Address.difference(s1.address, s2.address));
    return res;
}

//Add this in Address Class
public static List<String> difference(Address s1, Address s2) {
    List<String> res = new ArrayList<>();
    if (!s1.hno.equalsIgnoreCase(s2.hno)) res.add("adress.hno");
    if (!s1.street.equalsIgnoreCase(s2.street)) res.add("adress.street");
    if (s1.pin != s2.pin) res.add("pin");
    return res;
}

: [age, adress.hno, adress.street] ,

List<String> list = Student.difference(s1, s2);
System.out.println(list);

2.. , , :

//Add this method in Test Class
private static List<String> difference(Student s1, Student s2) throws IllegalAccessException {
    List<String> res = new ArrayList<>();
    for (Field f : s1.getClass().getFields())
        if (!f.get(s1).equals(f.get(s2)))
            res.add(f.getName());
    return res;
}

: [address, age] , ,

List<String> list = difference(s1, s2);
System.out.println(list);

3. :

  • constructor attributs,
  • public getters setters
  • equals
class Student {
    private String name;    private Address address;      private int age;      
    public Student (String n, Address ad, int a){name = n; address = ad; age=a;}
}

class Address {    
    private String hno;     private String street;        private int pin;
    public Address (String a, String s, int p){hno = a; street = s; pin=p;}    
}

//To use in your main of Test (or elsewhere) like this    
Student s1 = new Student("Krishna", new Address("2-2-22", "somewhere", 123), 30);
Student s2 = new Student("Krishna", new Address("1-1-11", "nowhere", 123), 20);           
-1
source

Source: https://habr.com/ru/post/1692364/


All Articles