Sobes.tech
Middle

Разкажи за договорите на методите equals и hashCode в Java.

sobes.tech AI

Отговор от AI

  • Рефлексивност: за всяка ненулева референтна стойност x, x.equals(x) трябва да връща true.

  • Симетрия: за всяка ненулева референтна стойност x и y, x.equals(y) трябва да връща true ако и само ако y.equals(x) връща true.

  • Транзитивност: за всяка тройка ненулеви референтни стойности x, y и z, ако x.equals(y) връща true и y.equals(z) връща true, тогава x.equals(z) трябва също да връща true.

  • Последователност: за всяка двойка ненулеви референтни стойности x и y, многократните извиквания на x.equals(y) трябва да връщат постоянно true или постоянно false, при условие че никаква информация, използвана в сравненията equals на обектите, не се променя между извикванията.

  • За всяка ненулева референтна стойност x, x.equals(null) трябва да връща false.

  • Ако два обекта са равни според метода equals(Object), тогава извикването на метода hashCode за всеки от двата обекта трябва да дава еднаква цяло число стойност.

  • Не е задължително, ако два обекта не са равни според метода equals(java.lang.Object), извикването на метода hashCode за всеки от двата обекта да дава различни цели числа. Въпреки това, програмистът трябва да разбира, че генерирането на различни хеш кодове за неравни обекти може да подобри производителността на хеш таблиците.

Важно е да се препишат и двата метода equals и hashCode, ако единият от тях е преписан, за да се поддържа контрактът. Използването на equals без преписване на hashCode може да доведе до неправилна работа на колекциите, базирани на хеширане (например, HashMap, HashSet).

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true; // Рефлексивност
        if (o == null || getClass() != o.getClass()) return false; // Проверка за null и тип
        Person person = (Person) o;
        return age == person.age &&
               Objects.equals(name, person.name); // Сравнение по съдържание
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age); // Генериране на хеш на базата на полетата
    }
}