Override `equals` method in Java
Tags: java
Published: 2018-04-10 20:28:43

---
title: Override `equals` method in Java
published: true
description: How to properly override the `equals` method
tags: Java
---

The `==` operator is a false friend in Java. It works properly only on primitive and will make you cry if you used it on any other referenced `Object`, for the most part.

## The basic

As a rule of thumb, every `equals` method should start like this:

```java
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }

        if (!(obj instance ClassName)) {
            return false;
        }

        // custom logic here
    }
```

The *ClassName* should be replaced by whatever type your class is. After that, I usually apply one of the following solutions.

### The class as only one relevant field

In the case that the class has only one relevant field, I will return automatically either the `==` operation (for primitive) or the `equals` of the field.

```java

public class Person

    private String fullname;

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }

        if (!(obj instance Person)) {
            return false;
        }

        Person converted = (Person)obj;

        return this.fullname.equals(converted.fullname);
    }

}
```

### The class as many relevant fields

I usually have two options here.

#### The `toString()` contains all the relevant field

There is no need to add complexity in a class if something can help you with your code. There is no need to test for `instanceof` since `toString` is defined everywhere, and no need to cast for the same reason.

```java

public class Person

    private String firstname;
    private String lastname;

    @Override
    public String toString() {
        return this.firstname + " " + this.lastname;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }

        return this.toString().equals(obj.toString());
    }

}
```

It is not mandatory to be the `toString`. Sometimes other methods do the same job. You need to keep in mind that other methods will require to test for and cast the object before comparing.

#### There is no method to help

In that situation, I will usually cascade `if` until the last relevant field.

```java

public class Person

    private String firstname;
    private String lastname;
    private Date dob;

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }

        if (!(obj instance Person)) {
            return false;
        }

        Person converted = (Person)obj;

        if (!(this.firstname.equals(converted.firstname)) {
            return false;
        }

        if (!(this.lastname.equals(converted.lastname)) {
            return false;
        }

        return this.dob.equals(converted.dob);
    }

}
```

I know that I could probably do something like this:

```java
    return this.firstname.equals(converted.firstname) && this.lastname.equals(converted.lastname) && this.dob.equals(converted.dob);
```

I don't really like this because it is mainly hard to read. I know that Java will probably optimize the bytecode with these kinds of statement, nevertheless, I believe that in most cases, it won't really matter.

Don't forget that, to be able to use `HashMap` and stuff, you also need to override the `hashcode`. Here are the main rules:

* If 2 instances are equal, then both `hashcode` MUST BE equal;
* If 2 instances are not equal, then both `hashcode` SHOULD NOT BE equal.

A good `hashcode` algorithm that lives up to the second rule will make the use of `HashMap` and `HashSet` more efficient.