Подтвердить что ты не робот

Когда мне нужно переопределить методы equals и hashcode?

Возможный дубликат:
Переопределение равных и hashCode в Java

Если у меня

class A {
    int x = 1;
}
...
A a1 = new A();
A a2 = new A();
a1.equals(a2);

Если я сравню два экземпляра A без переопределения метода equals, получу ожидаемый результат?

4b9b3361

Ответ 1

Если я сравню два экземпляра A без переопределения метода equals, получу ожидаемый результат?

Это зависит от того, что вы ожидаете:)

Реализация по умолчанию даст вам ссылочное равенство - другими словами, при сравнении двух ссылок equals будет возвращать true только в том случае, если они являются ссылками на один и тот же объект.

Обычно вы переопределяете equals для реализации "равенства значений" - где два разных объекта считаются равными, обычно в силу наличия одинаковых значений полей. Точный смысл равенства будет зависеть от вашего дизайна - два объекта все равно можно отличить, например, другими способами.

Если вы переопределяете equals, вы также должны переопределить hashCode, чтобы он соответствовал equals, так что если a.equals(b) истинно, тогда a.hashCode() == b.hashCode(). Это позволит использовать экземпляры вашего класса в качестве ключей в коллекциях, основанных на хеше (например, HashMap), чтобы вы могли искать значение на основе ключа, равного исходному, вместо того, чтобы использовать ссылку к конечному исходному ключевому объекту.

Ответ 2

Если я сравню два экземпляра A без переопределения метода equals, Я получаю ожидаемый результат?

Нет. Поскольку вы создали два разных экземпляра явно.

Почему? По умолчанию реализация equals проверяет, указывают ли два соответствующих объекта на одну и ту же ячейку памяти в виртуальной памяти Java (и это поведение по умолчанию определено в java.lang.Object.equals())

Когда мне нужно переопределить методы equals и hashcode?

Самый распространенный сценарий, когда программисты переопределяют оба equals() и hashcode(), - это если вам нужно использовать экземпляры соответствующего класса как

  • Ключи в реализациях java.util.Map
  • Значения в реализациях java.util.Set
  • Вы хотите проверить равенство значений между двумя разными экземплярами одного и того же класса (переопределение equals() является обязательным в этом случае, hashcode() не является - но является хорошей практикой программирования)

Общий контракт равных и хэш-код:

if a1.equals(a2)
    it is mandatory that a1.hashcode() == a2.hashcode()
if a1.hashcode() == a2.hashcode()
    it is not mandatory that a1.equals(a2)

Я думаю, что достаточно данных для обработки в течение дня:)

Ответ 3

Стандартная реализация equals проверяет, ссылаются ли переменные на один и тот же объект. Если это не то, что вы хотите, тогда вам нужно переопределить equals. Когда вы переопределяете equals, вам обычно нужно переопределить hashcode, чтобы объект можно было использовать в хэш-таблицах (или других структурах данных, которые используют хэш-коды).