I need to write some generic solution to find out what 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 anyone please suggest some solution?
PS
Overriding equals/hashcode is not an option for me.
I have written the below code but I am not sure how to identify if a type is complex (for example 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;
}
We use the hashcode() method to optimize performance when comparing objects. Executing hashcode() returns a unique ID for each object in your program, which makes the task of comparing the whole state of the object much easier.
The equals() method of the Object class compare the equality of two objects. The two objects will be equal if they share the same memory address. Syntax: public boolean equals(Object obj)
reflect. Field is used to compare two field objects. This method compares two field objects and returns true if both objects are equal otherwise false. The two Field objects are considered equal if and only if when they were declared by the same class and have the same name and type.
Comparing Objects ¶ When using the comparison operator ( == ), object variables are compared in a simple manner, namely: Two object instances are equal if they have the same attributes and values (values are compared with == ), and are instances of the same class.
This is an enhancement of Dumbo's difference
method, using recursion to check all nested complex fields.
private static void difference(Object s1, Object s2, List<String> changedProperties, String parent) throws IllegalAccessException {
for (Field field : s1.getClass().getDeclaredFields()) {
if (parent == null) {
parent = s1.getClass().getSimpleName();
}
field.setAccessible(true);
Object value1 = field.get(s1);
Object value2 = field.get(s2);
if (value1 == null && value2 == null) {
continue;
}
if (value1 == null || value2 == null) {
changedProperties.add(parent + "." + field.getName());
} else {
if (isBaseType(value1.getClass())) {
if (!Objects.equals(value1, value2)) {
changedProperties.add(parent + "." + field.getName());
}
} else {
difference(value1, value2, changedProperties, parent + "." + field.getName());
}
}
}
}
private static final Set<Class> BASE_TYPES = new HashSet(Arrays.asList(
String.class, Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Void.class));
public static boolean isBaseType(Class clazz) {
return BASE_TYPES.contains(clazz);
}
Sample usage (assumes the referenced model objects have getters/setters):
public static void main(String[] args) throws IllegalAccessException {
Student s1 = new Student();
s1.setName("Krishna");
s1.setAge(30);
Address address = new Address();
s1.setAddress(address);
s1.getAddress().setHno("2-2-22");
s1.getAddress().setStreet("somewhere");
s1.getAddress().setPin(123);
Student s2 = new Student();
s2.setName("Krishna");
s2.setAge(20);
address = new Address();
s2.setAddress(address);
s2.getAddress().setHno("1-1-11");
s2.getAddress().setStreet("nowhere");
s2.getAddress().setPin(123);
List<String> changedProperties = new ArrayList<>();
difference(s1, s2, changedProperties, null);
System.out.println("changedProperties = " + changedProperties);
// expected result
// Student.age
// Student.address.hno
// Student.address.street
}
Result:
changedProperties = [Student.address.hno, Student.address.street, Student.age]
Primitive adapting checking adapted from https://stackoverflow.com/a/711226/1527469
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With