Реализация объекта equals / hashcode хороша, если вы хотите использовать "ссылочную идентичность" в качестве равенства.Другими словами, объект on всегда будет сравниваться как равный самому себе, но отличающийся от другого объекта.
Если, однако, вы хотите, чтобы два разных объекта были равны, вы должны переопределить метод, чтобы сказать как они должны быть равны (а затем переопределить хеш-код, чтобы соответствовать этому).
Простейшим примером, вероятно, является String.Две разные строки с одинаковыми символами равны, и очень полезно , чтобы они были равны:
String x = new String(new char[]{'a', 'b', 'c'});
String y = new String(new char[]{'a', 'b', 'c'});
System.out.println(x.equals(y)); // Prints true
Теперь сравните это с FileInputStream
- что бы сделать два FileInputStreams равными?Если они читают один и тот же файл?Как насчет позиции в файле?Как насчет двух потоков в разные файлы с одинаковым содержимым?На самом деле не имеет большого смысла задавать вопрос, ИМО.
Теперь, как реализация Object
может узнать разницу между желаемым поведением FileInputStream
и String
?Он может потенциально принимать к сведению аннотации, добавленные к полям, свойствам и самому типу, возможно, автоматически генерируя соответствующий байт-код, который затем может быть скомпилирован в JIT ... но, конечно, Java появилась задолго до того, как аннотации стали доступны.Текущий подход очень прост - но он означает, что если вам нужно равенство значений для отдельных объектов, вам нужно кодировать его самостоятельно.
Следует отметить, что равенство обычно легче думать о неизменяемых типах -Странно, если два объекта равны в один момент времени, а потом не равны.Это также может серьезно испортить хеш-таблицы - хеш-код должен в основном зависеть от аспектов объекта, которые считаются равными, и хеш-код записывается при первом добавлении ключа в хеш-таблицу;если вы затем измените содержимое ключа, его хеш-код изменится, но хеш-таблица не узнает об этом.