Это похоже на работу во всех случаях
if(!empty(sizeof($array)))
Он работает для вас, потому что ваш код не использует никаких функций (HashMap, HashTable), которым нужен API hashCode()
.
Однако вы не знаете, является ли ваш класс (предположительно не написанным как одноразовый) позже будет вызываться в коде, который действительно использует его объекты как хэш-ключ, и в этом случае все будет затронуто.
В соответствии с документацией для класса Object :
Общий контракт hashCode:
blockquote>
- Всякий раз, когда он вызывается на одном и том же объекте более одного раза во время выполнения приложения Java, hashCode метод должен последовательно возвращать одно и то же целое число, если никакая информация, используемая при равных сравнениях с объектом, не изменяется. Это целое число не должно оставаться согласованным с одним исполнением приложения на другое выполнение одного и того же приложения.
- Если два объекта равны в соответствии с методом equals (Object), то вызов метода hashCode на каждом из два объекта должны иметь одинаковый целочисленный результат.
В первую очередь это важно при поиске объекта с использованием его значения hashCode () в коллекции (т. е. HashMap, HashSet и т. д.). Каждый объект возвращает другое значение hashCode (), поэтому вы должны переопределить этот метод, чтобы последовательно генерировать значение hashCode на основе состояния объекта, чтобы помочь алгоритму Collections найти значения в хеш-таблице.
Поскольку HashMap / Hashtable будет искать объект с помощью hashCode () первым.
Если они не совпадают, hashmap будет утверждать, что объект не совпадает и возврат не существует на карте.
Большинство других комментариев уже дали вам ответ: вам нужно это сделать, потому что есть коллекции (например, HashSet, HashMap), который использует hashCode в качестве оптимизации для «индексирования» экземпляров объекта, эти оптимизации предполагают, что если: a.equals(b)
==> a.hashCode() == b.hashCode()
(обратите внимание, что инверсия не выполняется).
Но в качестве дополнительной информации вы можете выполнить это упражнение:
class Box {
private String value;
/* some boring setters and getters for value */
public int hashCode() { return value.hashCode(); }
public boolean equals(Object obj) {
if (obj != null && getClass().equals(obj.getClass()) {
return ((Box) obj).value.equals(value);
} else { return false; }
}
}
это:
Set<Box> s = new HashSet<Box>();
Box b = new Box();
b.setValue("hello");
s.add(b);
s.contains(b); // TRUE
b.setValue("other");
s.contains(b); // FALSE
s.iterator().next() == b // TRUE!!! b is in s but contains(b) returns false
Что вы узнали из этого примера, так это то, что реализация equals
или hashCode
со свойствами, которые могут быть изменены (изменчивые), является действительно плохой идеей.
Причина, по которой вам нужно @Override
ни того, ни того и другого, связана с тем, как они взаимосвязаны с остальной частью API.
Вы обнаружите, что если вы поместите m1
в HashSet<MyCustomObject>
, то это не contains(m2)
. Это непоследовательное поведение и может вызвать множество ошибок и хаоса.
Библиотека Java имеет множество функциональных возможностей. Чтобы заставить их работать для , вам нужно играть по правилам и убедиться, что equals
и hashCode
являются совместимыми, является одним из самых важных.
hashCode
должен делать все возможное, чтобы не возвращать одно и то же целое число во многих значениях, которые могут возникнуть вместе во время одного и того же выполнения программы. У меня когда-то была ошибка производительности, и мне потребовалось много времени, чтобы отслеживать использование физического равенства вместе со стандартной (структурной) хэш-функцией. Это использование удовлетворяет вышеприведенным условиям, но все структурно идентичные, физически разные значения были хэшированы в одно и то же ведро. – Pascal Cuoq 25 April 2010 в 09:30