Equality – Part 1
September 14th, 2008
What is the proper way to compare two strings to determine if they contain the same text?
One of the hiccups new object-oriented programmers make revolves around comparing two objects for equality. The confusion typically stems from the initial learning of comparing two primitives:
int x = 0; int y = 0; boolean xyEqual = (x == y);
For primitives, the above code works correctly, in this case returning true. However, the == operator has a significantly different meaning when used to compare two objects. Take, for instance, the following small variation on the code:
Person x = new Person("Tyler Durden");
Person y = new Person("Tyler Durden");
boolean xyEqual = (x == y);
For simplicity, assume the Person constructor assigns the parameter to an internal attribute used to track the person’s name.
Based on the primitive example, the typical assumption is that the code would return true. As you might have guessed given the tone of this post, this is incorrect; the above condition will return false.
The reason lies in the polymorphic nature of the == operator. When applied to objects, this operator has a significantly different execution than it does for primitives.
When two objects are passed to the == operator, the result indicates if their object references are equal. In other words, this check will determine if they both point to the exact same object in memory. Since primitives are not objects, it’s understandable that there would be a different meaning when applied to objects.
Keep in mind that when calling new, a new object is created. In this light, it is clear why the above code evaluates to false. Compare this to the following:
Person x = new Person("Marla Singer");
Person y = x;
boolean xyEqual = (x == y);
This changes the condition to evaluate to true. The assignment in the second statement does not result in a new object creation, but rather indicates that y should point to the same object as x. Given the above definition of == when applied to objects, it should be clear why the result is true.
So how are two objects compared to see if they are semantically equal? The answer lies in the equals method defined in the base Object class. The signature of this method is as follows:
public boolean equals(Object other);
Domain objects often need to override this method in their implementations to provide a meaningful equality comparison. One note on the Object implementation, it defaults to == behavior, which is why fleshed out domain objects will override this method. Before we get to a possible implementation of this method for the Person class, let’s look at the properties this method must honor, as defined by the Java specification:
- It is reflexive: for any non-null reference value x,
x.equals(x)should returntrue. - It is symmetric: for any non-null reference values x and y,
x.equals(y)should returntrueif and only ify.equals(x)returnstrue. - It is transitive: for any non-null reference values x, y, and z, if
x.equals(y)returnstrueandy.equals(z)returnstrue, thenx.equals(z)should returntrue. - It is consistent: for any non-null reference values x and y, multiple invocations of
x.equals(y)consistently returntrueor consistently returnfalse, provided no information used in equals comparisons on the objects is modified. - For any non-null reference value x,
x.equals(null)should returnfalse.
With that in mind, let’s assume a person’s name is enough to identify them for equality. In reality, we’d probably use something guaranteed to be unique, such as a social security number or student/employee ID. But to stick with the above code snippet which only takes a name, we’ll use that.
1 2 3 4 | public boolean equals(Object other) { Person otherPerson = (Person)other; return this.getName().equals(otherPerson.getName()); } |
Since this method uses the same signature as defined in Object, this implementation will be invoked in all cases where the object is a Person. Instead of simply checking object references, this code will do an equality comparison on the person’s name, giving us the desired logic.
Note that this further uses the String class implementation of equals, which is the correct mechanism to use when comparing strings.
Keep in mind this is the Java specific mechanism. Other object-oriented languages have a similar construct, however the syntax will vary. For instance, in Python the == operator tests the values of two variables for equality. To do object reference checking in Python, the is operator is used.
There is much more to say on the topic, and will be covered in future blogs. Future installments include:
- This post makes no mention of the
hashCodemethod in theObjectclass. In many cases, both of these methods must be overridden at the same time. - The
Personclass implementation provided above makes a few assumptions. For now, I’ll leave it as an exercise to the reader to determine in what cases the above method will fail.

