What does equals(Object obj) do?

It redefines "equality" of objects.

By default (defined in java.lang.Object), an object is equal to another object only if it is the same instance. But you can provide custom equality logic when you override it.

For example, java.lang.String defines equality by comparing the internal character array. That's why:

String a = new String("a"); //but don't use that in programs, use simply: = "a"
String b = new String("a");
System.out.println(a == b); // false
System.out.println(a.equals(b)); // true

Even though you may not need to test for equality like that, classes that you use do. For example implementations of List.contains(..) and List.indexOf(..) use .equals(..).

Check the javadoc for the exact contract required by the equals(..) method.

In many cases when overriding equals(..) you also have to override hashCode() (using the same fields). That's also specified in the javadoc.


Different classes have different criteria for what makes 2 objects "equal". Normally, equals() returns true if it is the same Object:

Object a = new Object();
Object b = new Object();
return(a.equals(b));

This will return false, eventhough they are both "Object" classes, they are not the same instance. a.equals(a) will return true.

However, in cases like a String, you can have 2 different instances but String equality is based on the literal characters that make up those Strings:

String a = new String("example");
String b = new String("example");
String c = new String("another");
a.equals(b);
a.equals(c);

These are all different instances of String, but the first equals will return true because they are both "example", but the 2nd will not because "example" isn't "another".

You won't need to override equals() for every class, only when there is a special case for equality, like a class that contains 3 Strings, but only the first String is used for determining equality. In the example you posted, there could have been another field, description which could be different for 2 different "Contacts", but 2 "Contacts" will be considered equal if those 4 criteria match (first/last name, and home/cell phone numbers), while the description matching or not matching doesn't play into whether 2 Contacts are equal.


Aside from everything given by Bozho, there are some additional things to be aware of if overriding equals:

  • something.equals(null) must always return false - i.e. null is not equal to anything else. This requirement is taken care of in the second if of your code.

  • if it is true that something == something else, then also something.equals(something else) must also be true. (i.e. identical objects must be equal) The first if of your code takes care of this.

  • .equals SHOULD be symetric for non-null objects, i.e. a.equals(b) should be the same as b.equals(a). Sometimes, this requirement breaks if you are subclassing and overriding equals in the parent-class and in the subclass. Often equals contains code like if (!getClass().equals(other.getClass())) return false; that at least makes sure that a diffrent object type are not equal with each other.

  • If you override equals you also MUST override hashCode such that the following expression holds true: if (a.equals(b)) assert a.hashCode() == b.hashCode(). I.e. the hash code of two objects that are equal to each other must be the same. Note that the reverse is not true: two objects that have the same hash code may or may not be equal to each other. Ususally, this requirement is taken care of by deriving the hashCode from the same properties that are used to determine equality of an object.

In your case, the hashCode method could be:

public int hashCode() {
  return getFirstName().hashCode() +
    getLastName().hashCode() +
    getPhoneHome().hashCode() +
    getCellPhone().hashCode();
}
  • If you implement Comparable that compares two objects if they are smaller, larger, or equal to each other, a.compareTo(b) == 0 should be true if and only if a.equalTo(b) == true

In many IDEs (e.g. Eclipse, IntelliJ IDEA, NetBeans) there are features that generate both equals and hashCode for you, thereby sparing you of tedious and possibly error-prone work.

Tags:

Java