2014-06-29 3 views
0

Представьте, что мы имеем следующий простой изменяемых класса:Как сохранить хэш-код объекта согласованным во время выполнения приложений?

public class Point { 
    private int x; 
    private int y; 

    ... 

    public void addToX(int delta) { 
    x += delta; 
    } 

    public void addToY(int delta) { 
    y += delta; 
    } 
} 

Переопределение метода hashCode, используя только поле класса x и y не будет работать, так как значения могут изменяться во время выполнения, когда метод addToX/addToY является называется.

Так что мне было интересно, какая подходящая реализация hashCode будет для mutable классов?

+2

Это противоречивая цель. Если вы хотите, чтобы хэш-код был функцией значения объекта, и если значение объекта может измениться, вам придется принять, что хэш-код может измениться. –

+0

Вычислить хэш-код в первый раз и сохранить его в поле объекта. Используйте это значение при последующих вызовах. –

+0

Почему бы не принять оригинальный хэш-код? – Tony

ответ

3

Предполагая, что вы используете поля x и y в реализации Point # equals (Point p), нет необходимости сохранять Point # hashCode() согласованным в течение всего жизненного цикла объекта типа Point.

Действительно, Javadoc для класса java.lang.Object состояния для хэш-код(), что

Всякий раз, когда он вызывается на одном объекте более чем один раз в течение выполнения приложения Java, метод хэш-код последовательно должны возвращать то же целое

но есть заключение сразу после этого:

, не представили никакой информации, используемой в приравнивает сравнения на объекте модифицирована

смотри также http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()

+0

Благодарим вас за объяснение. Реализация хеш-кода с использованием полей классов x и y (а также их использование для метода equals), похоже, подходит для javadoc для класса java.lang.Object. Но разве это не так, так как изменение хеш-кода может вызвать проблемы при использовании HashSet например? –

+1

@JohnThreepwood: нет. Неправильно было бы хранить экземпляры изменяемого класса в HashSet и изменять их после. Но это не вина изменчивого класса. Это ошибка кода, использующего его. –

+0

@JBNizet: хороший пункт.Чтобы завершить этот ответ, вот две полезные ссылки для тех, кто хочет узнать больше о влиянии изменения хэш-кодов объектов после их хранения в контейнерах на основе хэша: см. Здесь [ссылка] http://stackoverflow.com/questions/6013631/can-hashcode-have-dynamic-changeable-content и здесь: [link] http://stackoverflow.com/questions/5174233/changing-hashcode-of-object-stored-in-hash-based-collection. Обратите внимание, однако, что эти проблемы не подразумевают, что вы вообще не можете иметь изменяемые поля в hashCode() и equals(). –

2

Вы подразумеваете в вашем вопросе о том, что класс не действительно представляют собой статическую точку, потому что вы можете изменить х и y. Вот почему хеш-код, основанный на значении x и y, кажется вам неправильным. Я думаю, что класс действительно представляет собой позицию, чьи значения x и y могут измениться. В этом случае есть атрибут, который вы подразумеваете, это идентификация этой позиции (например, положение автомобиля 37), и это идентификация не изменяется, даже если значения x/y изменяются. Вы хотите определить этот уникальный атрибут, добавить его в свой класс и создать свою хэш-код (и равна) по этому атрибуту.

Смежные вопросы