tags:

views:

728

answers:

9

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?

A: 

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)

Juan Manuel
+1  A: 

@Juan Manuel That may be the case in .NET but I think the intent of equals method in Java is different

N8g
Should be a comment, not an answer....
mikera
+17  A: 

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.

McDowell
The Effective Java (Josh Bloch; 1st ed.) chapter on java.lang.Object methods: http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf
McDowell
A: 

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.

Michael Sharek
+1  A: 

@Eli The argument I have heard most regarding not overiding the equals method usually boil down to either confusing other developers or running into issues if a framework/library you are utilizing depends on the default implementation of the method.

I would argue that these are both cases where the other programmer is not respecting the intent of the method and relying on the default implementation in a short sighted way.

N8g
+7  A: 

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.

David Schlosnagle
+3  A: 

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

Fredrik Kalseth
A: 

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.

serg10
+1  A: 

@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."

James A. Rosen