Sitemap
Büşra Erçelik

Büşra Erçelik

Software Developer

What makes two objects equal?

Reference Equality

2 min readJul 30, 2023

--

Consider you have a Beverage class and two Beverage references as below:

  @Test
void checkIfBeverageObjectsAreSame() {
Beverage milkshake = new Beverage("milkshake");
Beverage milk = milkshake;
assertSame(milk, milkshake);
assertEquals(milk.hashCode(), milkshake.hashCode());
}

These two references refer to the same object on the heap. If you don’t override the hashCode() method, Java assigns a unique hashcode based on the object’s memory address on the heap. We have two references but, one object on the heap. As a result here both references return the same hashCode() result.

if (milk == milkshake) { // true }

To see if two references refer to the same object use ‘== operator’. Java is pass-by-value which means it takes the bit pattern of the value and passes the copy of the pattern to a new variable. ‘== operator’ simply compares the pattern of bits in the variables. We don’t know the bit pattern of references, it’s dependent on JVM.

Object Equality

Suppose we have two references and two objects on the heap. If you want to see if two different objects are equal use equals() method.

@Test
void checkIfBeverageObjectsAreSame() {
Beverage milkshake = new Beverage("milkshake");
Beverage milk = new Beverage("milkshake");
assertNotSame(milk, milkshake);
}

As I said earlier, if you don’t override hashCode(), you inherit the default behavior from the class Object. I get these hashcodes for two references:

System.out.println(milkshake.hashCode()); // 1650967483
System.out.println(milk.hashCode()); // 87285178

We want to check if the two Beverages are the same if they have matching name variables. So we are going to override the hashCode() to get the same hashcode when we have identical name variables.

    @Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Beverage beverage = (Beverage) o;
return Objects.equals(name, beverage.name);
}

@Override
public int hashCode() {
return name.hashCode();
}

After overriding the hashCode and equals methods, let’s check if we get identical results:

System.out.println(milkshake.hashCode()); // -893680693
System.out.println(milk.hashCode()); // -893680693

Why do we override equals() along with hashCode()?

Get Büşra Erçelik’s stories in your inbox

Join Medium for free to get updates from this writer.

Well, two objects with the same hashcode might not be equal. The default behavior of equals() is to do an == comparison. If you don’t override equals(), no two objects will ever be equal.

If I override only hashCode(), the following line will return false since the objects are not equal.

 System.out.println(milk.equals(milkshake)); // false

So, if two objects are equal, calling equals() on either object must return true.

--

--