Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

Object equality

Writing equals and hashCode methods for data objects

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

Page 2 of 7

The equals() method's Javadoc declares that it must be:

Reflexive
An object must always be equal to itself; i.e., a.equals(a)
Symmetric
If two objects are equal, then they should be equal in both directions; i.e., if a.equals(b), then b.equals(a)
Transitive
If an object is equal to two others, then they must both be equal; i.e., if a.equals(b) and b.equals(c), then a.equals(c)
Non-null
An object can never be equal to null; i.e., a.equals(null) is always false


Fortunately, it is fairly easy to write a method that has this behavior. The equals method should compare:

  1. If the argument is this; if so, return true (reflexivity)
  2. If the argument is null; if so, return false (non-null)
  3. If the argument is of a different type; if so, return false (symmetry)
  4. Non-static and non-transient fields are equal, or both null in the case of reference types (symmetry, transitivity)


The reason why static fields are not compared is because they are the same for all class instances and thus clearly identical in an instance-based comparison. transient fields are not compared because the transient keyword's purpose is to prevent fields from being written during serialization; and these fields should therefore not play a part in equality testing. Otherwise, if an object is serialized and then de-serialized, then it will not be equal to itself.

Let's consider a simple point in 2D space to see how a simple equals() method looks; the comparison is shown graphically in Figure 1:

public class Point {
  private static double version = 1.0;
  private transient double distance;
  private int x, y;
  public boolean equals(Object other) {
    if (other == this) return true;
    if (other == null) return false;
    if (getClass() != other.getClass()) return false;
    Point point = (Point)other;
    return (x == point.x && y == point.y);
  }
}


Figure 1. Comparing fields in the Point class

The code above shows a simple example of an equals() method. Note that only the two non-static and non-transient fields (x and y) are being compared; the others (distance and version) are not relevant to instance-based comparison.

Note: In this case, the getClass() method is being used to determine whether the class is the correct type; this is the more correct choice than instanceof, as discussed below.

To compare whether two instances are of the same type, their getClass() method is invoked. Each instance has a single Class instance associated with it; classes of the same instance share exactly the same Class instance. In the VM, there is only a single Class instance for each class name (visible within a single ClassLoader, anyway). As a result, these Class instances can be compared with the identity test == instead of having to use an equals() on the Class instances.

Comparing reference types

So what happens when a reference type is declared within an object? The answer is that their equals() methods are used to compare the references directly; the only extra work involved is determining if the references are both null. The logic is:

  1. If the reference is null in this, then it must be null in the other
  2. If the reference is non-null in this, then it must be equals() in the other


Here's an example of a Person class that performs equality checking on two reference types, name and birth:

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comments (2)
Login
Forgot your account info?

When you need to compare objects Wich has specific rules for exaBy Anonymous on October 14, 2009, 2:09 pmWhen you need to compare objects Wich has specific rules for example.

Reply | Read entire comment

When to overwrite equals() and hashCode()By Anonymous on July 7, 2009, 3:08 amCan any pls tell in which case we have to overwrite equals() and hashCode()

Reply | Read entire comment

View all comments

Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources