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
- Если хэш-коды 2х объектов отличаются, то объекты точно разные
- Если хэш-коды 2х объектов равны, то это не значит что объекты тоже равны, т.к. он может просто совпасть.
- Если переопределяем 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