Question

I have always thought that the .equals() method in java should be overridden to be made specific to the class you have created. In other words to look for equivalence of two different instances rather than two references to the same instance. However I have encountered other programmers who seem to think that the default object behavior should be left alone and a new method created for testing equivalence of two objects of the same class.

What are the argument for and against overriding the equals method?

Was it helpful?

Solution

Overriding the equals method is necessary if you want to test equivalence in standard library classes (for example, ensuring a java.util.Set contains unique elements or using objects as keys in java.util.Map objects).

Note, if you override equals, ensure you honour the API contract as described in the documentation. For example, ensure you also override Object.hashCode:

If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

EDIT: I didn't post this as a complete answer on the subject, so I'll echo Fredrik Kalseth's statement that overriding equals works best for immutable objects. To quote the API for Map:

Note: great care must be exercised if mutable objects are used as map keys. The behavior of a map is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is a key in the map.

OTHER TIPS

I would highly recommend picking up a copy of Effective Java and reading through item 7 obeying the equals contract. You need to be careful if you are overriding equals for mutable objects, as many of the collections such as Maps and Sets use equals to determine equivalence, and mutating an object contained in a collection could lead to unexpected results. Brian Goetz also has a pretty good overview of implementing equals and hashCode.

You should "never" override equals & getHashCode for mutable objects - this goes for .net and Java both. If you do, and use such an object as the key in f.ex a dictionary and then change that object, you'll be in trouble because the dictionary relies on the hashcode to find the object.

Here's a good article on the topic: http://weblogs.asp.net/bleroy/archive/2004/12/15/316601.aspx

@David Schlosnagle mentions mentions Josh Bloch's Effective Java -- this is a must-read for any Java developer.

There is a related issue: for immutable value objects, you should also consider overriding compare_to. The standard wording for if they differ is in the Comparable API:

It is generally the case, but not strictly required that (compare(x, y)==0) == (x.equals(y)). Generally speaking, any comparator that violates this condition should clearly indicate this fact. The recommended language is "Note: this comparator imposes orderings that are inconsistent with equals."

The Equals method is intended to compare references. So it should not be overriden to change its behaviour.

You should create a new method to test for equivalence in different instances if you need to (or use the CompareTo method in some .NET classes)

To be honest, in Java there is not really an argument against overriding equals. If you need to compare instances for equality, then that is what you do.

As mentioned above, you need to be aware of the contract with hashCode, and similarly, watch out for the gotchas around the Comparable interface - in almost all situations you want the natural ordering as defined by Comparable to be consistent with equals (see the BigDecimal api doc for the canonical counter example)

Creating a new method for deciding equality, quite apart from not working with the existing library classes, flies in the face of Java convention somewhat.

You should only need to override the equals() method if you want specific behaviour when adding objects to sorted data structures (SortedSet etc.)

When you do that you should also override hashCode().

See here for a complete explanation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top