Home > Software engineering >  Find difference of two object of same Pojo in Java
Find difference of two object of same Pojo in Java

Time:05-11

public static Map<String, Object> difference(Organization current, Organization prev) throws IllegalArgumentException, IllegalAccessException{
    Map<String, Object> changedProperties = new HashMap<>();
    for(Field field : current.getClass().getDeclaredFields()){
        field.setAccessible(true);
        Object value1 = field.get(current);
        Object value2 = field.get(prev);
        if(value1 != null && value2 != null) {
            if(value1.getClass() == String.class) { //if property is type of String
                if(!Objects.equals(value1, value2)) {
                    changedProperties.put(field.getName(), (String) value1);
                }
            }else {
                if(!Objects.equals(value1, value2)) {
                    for(Field cur : value1.getClass().getDeclaredFields()){
                        for(Field pre : value2.getClass().getDeclaredFields()){
                            cur.setAccessible(true);
                            pre.setAccessible(true);
                            
                            if(cur.getName().equals(pre.getName())) { //compare same type of properties like Contact1 with Contact2
                                Object val1 = cur.get(value1);
                                Object val2 = pre.get(value2);
                                
                                if(val1 == null && val2 == null) {
                                    //Do nothing
                                }else {
                                    changedProperties.put(cur.getName(), val1);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return changedProperties;
}

Here is my Pojo

@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@ToString
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Organization {

    private String unitId;
    
    private String unitType;
    
    private Contact contact; 
}


@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@ToString
@JsonInclude(JsonInclude.Include.NON_NULL)
class Contact{
    private Name name;
    private Address address;
    private List<Phone> phones;
 }


@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@ToString
@JsonInclude(JsonInclude.Include.NON_NULL)
class Name{
    private String brandName;
    private String department;
}


@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@ToString
@JsonInclude(JsonInclude.Include.NON_NULL)
class Address{
    private String addressLine1;
    private String addressLine2;
    private String postalCode;
    private String city;
}


@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@ToString
@JsonInclude(JsonInclude.Include.NON_NULL)
class Phone{
    private String id;
    private String number;
    private Boolean primary;
    private String comment;
}

I am able to get the differences of the two objects of same POJO but I need to maintain hierarcy, meaning I want this as difference : contact=Contact(phones=[Phone(id=1, number=46127, primary=true, comment=null)]) instead of this : phones=[Phone(id=1, number=46127, primary=true, comment=null). Please help.

CodePudding user response:

In Java, you can override the equals() method for your objects. If you have properties and those properties are custom objects you can call equals() method for those some objects. For example, in your Organization object you can create this method.

@Override
public boolean equals(Organization org){
   return org.getUnitId() != null && org.getUnitType() != null && org.getContact() != null && org.getUnitId().equals(this.getUnitId()) && org.getUnitType().equals(this.getUnitType) && org.getContact().equals(this.getContact());
}

Also, you need to create the equals for Contact in the same way:

@Override
public boolean equals(Contact contact){
 //your custom equals for contact, this method is being called in equals() from Organization.
}

and then when you compare Organization, the nested object will be compared to. Apart of equals, you can override compareTo().

More info here: https://www.geeksforgeeks.org/overriding-equals-method-in-java/

CodePudding user response:

You could do something like:

@Override
public boolean equals(Object other) {
    if (!(other instanceof Organization )) {
        return false;
    }

    Organization that = (Organization ) other;

    // Custom equality check here.
    return this.field1.equals(that.field1)
        && this.field2.equals(that.field2);
}

Also if you are storing in a hash table you would need to implement hashcode too

@Override
public int hashCode() {
int hashCode = 1;

hashCode = hashCode * 37   this.unitId.hashCode();
hashCode = hashCode * 37   this.unitTypeId.hashCode();
hashCode = hashCode * 37   this.contact.getName().hashCode();

return hashCode;
}
  • Related