> For the complete documentation index, see [llms.txt](https://gyansetu-core-java-for-java.gitbook.io/project/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gyansetu-core-java-for-java.gitbook.io/project/equals-and-hashcode.md).

# 5) Equals and Hashcode

## ***1) equals()***

The *Object* class defines both the *equals()* and *hashCode()* methods – which means that these two methods are implicitly defined in every Java class, including the ones we create:

![](/files/-LaVw1SzGSSiB3WQq98K)

We would expect *income.equals(expenses)* to return *true*. But with the *Money* class in its current form, it won’t.

**The default implementation of&#x20;*****equals()*****&#x20;in the class&#x20;*****Object*****&#x20;says that equality is the same as object identity. And&#x20;*****income*****&#x20;and&#x20;*****expenses*****&#x20;are two distinct instances.**

### **Without Equals :**

```java
package com.gs.ilp.corejava.collectionsFramework2.equalsandhashcode;

public class WrongMoney {
	int amount;
	String currencyCode;

	public WrongMoney() {
		super();
		// TODO Auto-generated constructor stub
	}

	public WrongMoney(int amount, String currencyCode) {
		super();
		this.amount = amount;
		this.currencyCode = currencyCode;
	}

}
```

```java
package com.gs.ilp.corejava.collectionsFramework2.equalsandhashcode;

public class TestWrongMoney {
	public static void main(String[] args) {
		WrongMoney income = new WrongMoney(55, "USD");
		WrongMoney expenses = new WrongMoney(55, "USD");
		boolean balanced = income.equals(expenses);
		System.out.println("Are the equal :" + balanced);
	}

}
```

![](/files/-Lapm0Gg2fjDle5nVqcF)

### ***1.1)*****&#x20;Overriding&#x20;*****equals()***

Let’s override the *equals()* method so that it doesn’t consider only object identity, but rather also the value of the two relevant properties:

![](/files/-LaVwJ7x_emA5E-Czlrd)

### Genrating Equals/Hashcode using Eclipse:

#### Way 1:  Using getClass()

![](/files/-LaprbVDeCKhA_fZru7p)

![](/files/-LapreFxd8CQk04A6UAy)

```java
package com.gs.ilp.corejava.collectionsFramework2.equalsandhashcode;

public class Money {
	int amount;
	String currencyCode;

	public Money() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Money(int amount, String currencyCode) {
		super();
		this.amount = amount;
		this.currencyCode = currencyCode;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Money other = (Money) obj;
		if (amount != other.amount)
			return false;
		if (currencyCode == null) {
			if (other.currencyCode != null)
				return false;
		} else if (!currencyCode.equals(other.currencyCode))
			return false;
		return true;
	}

}
```

#### Way 2: Using instanceOf()

![](/files/-LaprkVZyx7woLELMiH8)

### With Equals :

```java
package com.gs.ilp.corejava.collectionsFramework2.equalsandhashcode;

public class Money {
	int amount;
	String currencyCode;

	public Money() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Money(int amount, String currencyCode) {
		super();
		this.amount = amount;
		this.currencyCode = currencyCode;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Money))
			return false;
		Money other = (Money) obj;
		if (amount != other.amount)
			return false;
		if (currencyCode == null) {
			if (other.currencyCode != null)
				return false;
		} else if (!currencyCode.equals(other.currencyCode))
			return false;
		return true;
	}

	

}

```

```java
package com.gs.ilp.corejava.collectionsFramework2.equalsandhashcode;

public class TestMoney {
	public static void main(String[] args) {
		Money income = new Money(55, "USD");
		Money expenses = new Money(55, "USD");
		boolean balanced = income.equals(expenses);
		System.out.println("Are the equal :"+balanced);
	}
}
```

![](/files/-LapmQszcZwHBKkx-vUK)

### [***https://stackoverflow.com/questions/596462/any-reason-to-prefer-getclass-over-instanceof-when-generating-equals***](https://stackoverflow.com/questions/596462/any-reason-to-prefer-getclass-over-instanceof-when-generating-equals)

### **1.2)&#x20;*****equals()*****&#x20;Contract**

Java SE defines a contract that our implementation of the *equals()* method must fulfill. **Most of the criteria are common sense.** The *equals()* method must be:

* *reflexive*: an object must equal itself
* *symmetric*: ***x.equals(y)*****&#x20;must return the same result as&#x20;*****y.equals(x)***
* *transitive*: if *x.equals(y)* and *y.equals(z)* then also *x.equals(z)*
* *consistent*: the value of *equals()* should change only if a property that is contained in *equals()* changes (no randomness allowed)

We can look up the exact criteria in the [Java SE Docs for the *Object* class](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Object.html).

### **1.3)  Violating&#x20;*****equals()*****&#x20;Symmetry with Inheritance**

If the criteria for *equals()* is such common sense, how can we violate it at all? Well, **violations happen most often, if we extend a class that has overridden&#x20;*****equals()*****.** Let’s consider a *Voucher* class that extends our *Money* class:

![](/files/-LaVwfI40XpiWcaD_V0w)

At first glance, the *Voucher* class and its override for *equals()* seem to be correct. And both *equals()*&#x6D;ethods behave correctly as long as we compare *Money* to *Money* or *Voucher* to *Voucher*. **But what happens, if we compare these two objects?**

![](/files/-LaVwr74F4AmNNCQBrXF)

**That violates the symmetry criteria of the&#x20;*****equals()*****&#x20;contract.**

```java
package com.gs.ilp.corejava.collectionsFramework2.equalsandhashcode;

public class WrongVoucher extends Money {

	private String store;

	public WrongVoucher(String store) {
		super();
		this.store = store;
	}

	public WrongVoucher() {
		super();
		// TODO Auto-generated constructor stub
	}

	public WrongVoucher(int amount, String currencyCode, String store) {
		super(amount, currencyCode);
		this.store = store;
		// TODO Auto-generated constructor stub
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (!(obj instanceof WrongVoucher))
			return false;
		WrongVoucher other = (WrongVoucher) obj;
		if (store == null) {
			if (other.store != null)
				return false;
		} else if (!store.equals(other.store))
			return false;
		return true;
	}
}
```

```java
package com.gs.ilp.corejava.collectionsFramework2.equalsandhashcode;

public class TestWrongVoucher {
	public static void main(String[] args) {
		Money cash = new Money(42, "USD");
		WrongVoucher voucher = new WrongVoucher(42, "USD", "Amazon");

		System.out.println(voucher.equals(cash));
		System.out.println(cash.equals(voucher));
	}
}
```

![](/files/-Lapt1wyx58o0_AvP2rr)

### **1.4) Way 1: Using getClass instead of instanceOf()**

**Refer to** Way 1:  Using getClass()

#### Example 2:

{% embed url="<https://stackoverflow.com/questions/13162188/java-equals-method-in-base-class-and-in-subclasses>" %}

### **1.4)&#x20;*****Way 2 :*****&#x20;Fixing&#x20;*****equals()*****&#x20;Symmetry with Composition**

To avoid this pitfall, we should **favor composition over inheritance.**

Instead of subclassing *Money*, let’s create a *Voucher* class with a *Money* property:

![](/files/-LaVx5SxPBmlPrPi_hDX)

And now, *equals* will work symmetrically as the contract requires.

## **2.&#x20;*****hashCode()***

*hashCode()* returns an integer representing the current instance of the class. We should calculate this value consistent with the definition of equality for the class. Thus **if we override the&#x20;*****equals()*** method, we also have to override *hashCode()*.

For some more details, check out our [guide to *hashCode()*](https://www.baeldung.com/java-hashcode).

### **2.1)&#x20;*****hashCode()*****&#x20;Contract**

Java SE also defines a contract for the *hashCode()* method. A thorough look at it shows how closely related *hashCode()* and *equals()* are.

**All three criteria in the contract of&#x20;*****hashCode()*****&#x20;mention in some ways the&#x20;*****equals()*****&#x20;method:**

* *internal consistency*: **the value of&#x20;*****hashCode()*****&#x20;may only change if a property that is in&#x20;*****equals()*****&#x20;changes**
* *equals consistency*: **objects that are equal to each other must return the same hashCode**
* *collisions*: **unequal objects may have the same hashCode**

### **2.2) Violating the Consistency of&#x20;*****hashCode()*****&#x20;and&#x20;*****equals()***

The 2nd criteria of the hashCode methods contract has an important consequence: **If we override equals(), we must also override hashCode().** And this is by far the most widespread violation regarding the contracts of the *equals()* and *hashCode()* methods.

Let’s see such an example:

![](/files/-LaVxWX28gvCcRog1Rvf)

The *Team* class overrides only *equals()*, but it still implicitly uses the default implementation of *hashCode()* as defined in the *Object* class. And this returns a different *hashCode()* for every instance of the class. **This violates the second rule.**

Now if we create two *Team* objects, both with city “New York” and department “marketing”, they will be equal, **but they will return different hashCodes.**

### **2.3)&#x20;*****HashMap*****&#x20;Key with an Inconsistent&#x20;*****hashCode()***

But why is the contract violation in our *Team* class a problem? Well, the trouble starts when some hash-based collections are involved. Let’s try to use our *Team* class as a key of a *HashMap*:

![](/files/-LaVxjlA1wwIipOG_XtV)

We would expect *myTeamLeader* to return “Anne”. **But with the current code, it doesn’t.**

If we want to use instances of the *Team* class as *HashMap* keys, we have to override the *hashCode()*&#x6D;ethod so that it adheres to the contract: **Equal objects return the same&#x20;*****hashCode.***

Let’s see an example implementation:

![](/files/-LaVxqPvvMrgWJopV0-g)

### Example : *collisions*: **unequal objects may have the same hashCode**

```java
package com.gs.ilp.corejava.collectionsFramework2.equalsandhashcode;

public class Doctor {
	private String fName;
	private String lName;

	/**
	 * @param fName
	 * @param lName
	 */
	public Doctor(String fName, String lName) {
		this.fName = fName;
		this.lName = lName;
	}

	@Override
	public int hashCode() {
		int result = fName.hashCode() + lName.hashCode();
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Doctor other = (Doctor) obj;
		if (fName == null) {
			if (other.fName != null)
				return false;
		} else if (!fName.equals(other.fName))
			return false;
		if (lName == null) {
			if (other.lName != null)
				return false;
		} else if (!lName.equals(other.lName))
			return false;
		return true;
	}

}
```

```java
package com.gs.ilp.corejava.collectionsFramework2.equalsandhashcode;

public class TestDoctorHashcodeRule3 {
	public static void main(String[] args) {
		Doctor doctor1 = new Doctor("Mohit", "Vijay");
		Doctor doctor2 = new Doctor("Vijay", "Mohit");
		System.out.println(
				"Doctors having different objects with different values but they still can have same hashcode");
		System.out.println("Are they equal " + doctor1.equals(doctor2));
		System.out.print("Do the have same hashcode ");
		if (doctor1.hashCode() == doctor2.hashCode()) {
			System.out.println(true);
		} else {
			System.out.println(false);
		}
		System.out.println("Hashcode of doctor 1 " + doctor1.hashCode());
		System.out.println("Hashcode of doctor 2 " + doctor2.hashCode());
	}

}
```

![](/files/-LapxqDc-JusXmqI308a)

### **3. When Do We Override&#x20;*****equals()*****&#x20;and&#x20;*****hashCode()*****?** <a href="#override" id="override"></a>

**Generally, we want to override either both of them or neither of them.** We’ve just seen in Section 3 the undesired consequences if we ignore this rule.

Domain-Driven Design can help us decide circumstances when we should leave them be. For entity classes – for objects having an intrinsic identity – the default implementation often makes sense.

However, **for value objects, we usually prefer equality based on their properties**. Thus want to override *equals()* and *hashCode()*. Remember our *Money* class from Section 1: 55 USD equals 55 USD – even if they’re two separate instances.

### **4. Implementation Helpers**

We typically don’t write the implementation of these methods by hand. As can be seen, there are quite a few pitfalls.

One common way is to let our IDE generate the *equals()* and *hashCode()* methods.

Apache Commons Lang and Google Guava have helper classes in order to simplify writing both methods.

Project Lombok also provides an *@EqualsAndHashCode* annotation. **Note again how&#x20;*****equals()*****&#x20;and&#x20;*****hashCode()*****&#x20;“go together” and even have a common annotation.**

### **6. Verifying the Contracts**

If we want to check whether our implementations adhere to the Java SE contracts and also to some best practices, **we can use the EqualsVerifier library.**

Let’s add the [EqualsVerifier](https://mvnrepository.com/artifact/nl.jqno.equalsverifier/equalsverifier) Maven test dependency:

Let’s verify that our *Team* class follows the *equals()* and *hashCode()* contracts:

It’s worth noting that *EqualsVerifier* tests both the *equals()* and *hashCode()* methods.

***EqualsVerifier*****&#x20;is much stricter than the Java SE contract.** For example, it makes sure that our methods can’t throw a *NullPointerException.* Also, it enforces that both methods, or the class itself, is final.

It’s important to realize that **the default configuration of&#x20;*****EqualsVerifier*****&#x20;allows only immutable fields**. This is a stricter check than what the Java SE contract allows. This adheres to a recommendation of Domain-Driven Design to make value objects immutable.

If we find some of the built-in constraints unnecessary, we can add a *suppress(Warning.SPECIFIC\_WARNING)* to our *EqualsVerifier* call.

### **7. Conclusion**  <a href="#conclusion" id="conclusion"></a>

We should remember to:

* Always override *hashCode()* if we override *equals()*
* Override *equals()* and *hashCode()* for value objects
* Be aware of the traps of extending classes that have overridden *equals()* and *hashCode()*
* Consider using an IDE or a third-party library for generating the *equals()* and *hashCode()* methods
* Consider using EqualsVerifier to test our implementation

Finally, all code examples can be found [over on GitHub](https://github.com/mmalhotra2000/corejavatutorials).<br>
