views:

1008

answers:

4

I have an object which itself has multiple objects as fields. The question I have is, I have two objects of these kind and I want to compare these two. I know I can do equals, comparator etc. but is there a way to use reflection to get the properties of the object and make comparison.

for example, if I have a Car object, which as wheels object, which has tires object, which has bolts object. Please remember all the above objects are individual and not nested classes. How do I compare 2 car objects?

Any help is appreciated?

Thanks

+10  A: 

Apache Commons Lang has an EqualsBuilder class that does exactly this (see the reflectionEquals() methods)

 public boolean equals(Object obj) {
   return EqualsBuilder.reflectionEquals(this, obj);
 }

EqualsBuilder also provides more explicit methods for null-safe comparison of specific fields, which makes writing "proper" (i.e. non-reflective) equals methods a bit less onerous.

skaffman
If you're interested in performance of the reflection approach you might want to have a look here: http://blog.xebia.com/2009/04/24/declarative-equality-for-your-business-domain-objects/
p3t0r
+7  A: 
public class Car {
  private Wheels wheels;
  // other properties

  public boolean equals(Object ob) {
    if (!(ob instanceof Car)) return false;
    Car other = (Car)ob;
    // compare properties
    if (!wheels.equals(other.wheels)) return false;
    return true;
  }
}

is the correct approach. Automatic comparison via reflection is not recommended. For one thing "state" is a more generic concept than reflected property comparison.

You could write something that did deep reflection comparison but it's kinda missing the point.

cletus
You need add checks for if ob == null return false, if ob == this return true to complete the equals method.
Droo
The `instanceof` will take care of the null case. `this` comparison is not necessary, although it may help performance. What is probably wrong is the use of `instanceof` with a non-`final` class - make the class `final` (or use `Object.getClass` if you really must).
Tom Hawtin - tackline
Agreed with Tom, you might not want to write equals() in such a way that it's possible for a subclass of Car to be equal to an instance of Car, since this means your equals() would not be symmetric
matt b
this seems to be the direction I should take, every article online also points this way. Thanks for all the comments guys
codeModuler
+2  A: 

Most modern IDE's have generators for hashcode and equals which let you select the properties to take into account. Those beat performance of their reflective counterparts easily.

p3t0r
A: 

The idea is interesting, but please be aware that reflection can be slow. If you need to do a lot of comparisons, or you are putting your objects in collection classes that do comparisons (for example HashMap, HashSet etc.) then comparing objects via reflection can become a performance bottleneck.

Jesper