объекты хеширования Java - PullRequest
0 голосов
/ 28 января 2012

Я хотел бы иметь возможность определить, сталкивался ли я ранее с объектом - у меня есть реализация графа, и я хочу посмотреть, создал ли я цикл, возможно, путем перебора объектов Node с черепахой /алгоритм заяц Флойд.

Но я хочу избегать линейного поиска в моем списке «видимых» узлов каждый раз.Это было бы здорово, если бы у меня была хеш-таблица только для ключей.Можно ли как-то хешировать объект?Разве ява-объекты не являются ссылками на места в памяти?Интересно, сколько будет проблемных коллизий, если да ..

Ответы [ 4 ]

5 голосов
/ 28 января 2012

Простой ответ - создать HashSet и добавить каждый узел к набору при первом его обнаружении.

Единственный случай, когда это не сработает, это если вы перегружены hashCode() и equals(Object) для класса узла для реализации равенства на основе содержимого узла (или чего-либо еще).Тогда вам нужно:

  • использовать класс IdentityHashMap, который использует == и System.identityHashcode вместо equals(Object) и hashCode(), или
  • построитьхэшируй себя, используя свой собственный вид идентичности объекта.

Разве ява-объекты не являются ссылками на места в памяти?

Да и нет.Да, ссылка представлена ​​адресом памяти (в большинстве JVM).Проблема в том, что 1) вы не можете получить адрес, и 2) он может измениться, когда GC перемещает объект.Это означает, что вы не можете использовать адрес объекта в качестве хеш-кода.

Метод identityHashCode решает эту проблему, возвращая значение, которое изначально на основе адреса памяти.Если затем вы снова вызовете identityHashCode для того же объекта, вы гарантированно получите то же значение, что и раньше ... даже если объект был перемещен.

Интересно, сколько проблемСтолкновения были бы, если так ..

Значения хеша, полученные методом identityHashCode, могут конфликтовать.(То есть два различных объекта могут иметь одинаковое значение хэш-кода идентификатора.) Все, что использует эти значения, должно иметь дело с этим.(Стандартные классы HashSet и IdentityHashMap заботятся об этих коллизиях ... если вы решили их использовать.)

4 голосов
/ 28 января 2012

Я бы хотел определить, сталкивался ли я с объектом ранее

Использовать IdentityHashMap .Это идеальный вариант для вашей работы, поскольку это не equals, а == реализация.

2 голосов
/ 28 января 2012

Взгляните на HashSet .Обратите внимание, что для того, чтобы объекты работали с HashSet, им необходимо предоставить правильные реализации hashCode и equals методов класса java.lang.Object.

1 голос
/ 28 января 2012

Вам нужно будет реализовать хеш-функцию для ваших объектов. Это делается путем переопределения hashCode(), определенного в java.lang.Object. Этот метод используется HashMap, HashSet и т. Д. Для хранения объектов. В hashCode() вы должны вычислить хеш для объекта. Не забудьте также реализовать equals() -метод!

Взгляните на структуру коллекции Java (http://docs.oracle.com/javase/tutorial/collections/)

...