开发者

Diff between two instances of same class [duplicate]

开发者 https://www.devze.com 2023-01-11 14:31 出处:网络
This question already has answers here: find out the differences between two java beans for version tracking
This question already has answers here: find out the differences between two java beans for version tracking (4 answers) Closed 6 years ago.

I have two instances of the same class. I need to find property(s) which are different amongst them (basically value of the property, say firstName might be different in both). The fields are primitive, complex as well as collections.

Ba开发者_运维百科sically, I need to find differences between two instances and if the fields are different in both the instances, I will copy value of the field from first instance to a third instance (diff object).

I think I can use reflection, but the classes are very complex and it might become error prone.


Your question is a bit unclear. First you said "two instances of the same class", then you said "the classes are very complex". Is this a generic solution to find differences between instances for any class, or is it just a specific case? The other ambiguity is what you mean by "copy the differences". For example, if its a String, then what is the difference between the two strings that would get copied into the new instance? If its a collection, what is the difference between the collections? What if you have two ArrayLists that have the same things in different orders.

If its a specific case, then you can just create a method on the class where you pass in an instance of the same class. Then you can iterate over each field and compare the differences.

public TheClass difference(TheClass that) {
  TheClass newClass = new TheClas()
  if (this.getName().equals(that.getName()) == false ) {
    newClass.setName(that.getName());
  }
  ...
}

But this can get out of hand depending on how deep your object graph is.

Perhaps the builder pattern might come in handy here if you're trying to build a generic/reusable solution. You might look at the Apache Commons code base and see how they implement HashCodeBuilder and ToStringBuilder. They even have a reflection version of the utilities. See how they handle deep and shallow equals.


There is no other way than to use reflection if you want to do it generically. If your fields have getters then you could keep comparing it with equals method. Then you have know the fields at compile time.


write a method like

public YourClass diff(YourClass other) {
    // diff code here
}

or

public static YourClass diff(YourClass first, YourClass second) {
    // diff code here
}

and wrap some unit tests around the implementations.

Reflection might seem more complicated, but it has the following advantages:

1) It can be generic and you can make the same code work with any class
2) It will not have to be changed if the class evolves.

If you want to go with reflection, you can use Class.getDeclaredFields() (google for "java class api 6") to get all the fields on the class, and then you can use the Field api to get the values for an object. If you wanted to be really fancy, you have a static String[] "diffIgnoredFields" and include field names you want to ignore in the diff.


You need to be careful. Some formulations of this problem are essentially the same as the Subgraph Isomorphism Problem which is known to be NP complete.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号