Equals и hashCode

Equals и hashCode


В главное меню


Equals

В JAVA создадим класс, добавим конструктор, поля, геттеры и сеттеры

public class Address {
    private String city;
    private String street;
    private int numberOfHouse;

    public Address(String city, String street, int numberOfHouse) {
        this.city = city;
        this.street = street;
        this.numberOfHouse = numberOfHouse;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public int getNumberOfHouse() {
        return numberOfHouse;
    }

    public void setNumberOfHouse(int numberOfHouse) {
        this.numberOfHouse = numberOfHouse;
    }
}

При попытке сравнения 2х объектов через == окажется что они не равны.

public class Main {
    public static void main(String[] args) {
        Address address1  = new Address("Москва", "Зелёная", 150);
        Address address2  = new Address("Москва", "Зелёная", 150);
        if (address1 == address2) {
            System.out.println("Равны");
        } else {
            System.out.println("Не равны");
        }
    }
}
----------------------------------
Не равны


Дело в том, что происходит сравнение ссылок этих объектов. При инициализации переменной ей присваивается ссылка на объект. Сам объект хранится в куче, переменная хранится в стеке.

Мы можем воспользоваться equals для сравнения

if (address1.equals(address2)) {
    System.out.println("Равны");
} else {
    System.out.println("Не равны");
}

Но результат не поменяется, т.к. его нужно переопределить в классе Address

@Override
public boolean equals(Object obj) {
    if(obj instanceof Address address) {
        return this.city.equals(address.city) && this.street.equals(address.street) && this.numberOfHouse == address.numberOfHouse;
    }
    else return false;
}


hashCode

address1.hashCode
  1. Если хэш-коды 2х объектов отличаются, то объекты точно разные
  2. Если хэш-коды 2х объектов равны, то это не значит что объекты тоже равны, т.к. он может просто совпасть.
  3. Если переопределяем equals то и переопределить hashCode
@Override
public int hashCode() {
    return city.hashCode() + street.hashCode() + numberOfHouse;
}


Объектов может быть сколько угодно, а разных кодов миллиарды


Теперь добавим проверку по кодам в equals

@Override
public boolean equals(Object obj) {
    if (hashCode() != obj.hashCode()) {
        return false;
    }
    if(obj instanceof Address address) {
        return this.city.equals(address.city) && this.street.equals(address.street) && this.numberOfHouse == address.numberOfHouse;
    }
    else return false;
}

Если хэш коды не равны, то объекты точно не равны.


Можно ещё оптимизировать добавив сравнение ссылок объекта.

if (this == obj) {
    return true;
}

Если ссылки равны - то это точно один объект!


Идя сама может это реализовать. alt+insert - equals and HashCode

Report Page