Java: HashMap утверждает, что у него есть ключ, но почему-то нет - PullRequest
0 голосов
/ 30 августа 2011

У меня есть объекты HashMap, сопоставляющие мой класс Context с целыми числами. В классе Context я переопределил public int hashCode () и public boolean equals (Object c) из java.lang.Object. Тем не менее, у меня есть проблемы с его повторением:

Я хочу (например) получить значение Integer, назначенное каждому объекту Context, поэтому я перебираю набор ключей карты. Но это не работает, потому что карта говорит, что не имеет указанного ключа:

for (Context to : map.keySet()) {
    System.out.println("to-hash: " + to.hashCode());
    System.out.println("first-hash: " + map.keySet().iterator().next().hashCode());
    System.out.println("hashs equal: " + (to.hashCode()==map.keySet().iterator().next().hashCode()));
    System.out.println("to equals first: " + to.equals(map.keySet().iterator().next()));
    System.out.println("map has to? " + map.containsKey(to));
}

Выход

to-hash: 156349
first-hash: 156349
hashs equal: true
to equals first: true
map has to? false

Насколько я понимаю, когда дан ключ, карта сначала проверяет, совпадают ли хеш-коды, а затем проверяет равенство. Здесь и то и другое: хеш-код объекта to и первый объект в наборе ключей совпадают, и они также равны. Интересно, что когда я меняю возвращаемое значение функции hashCode () на константу (которая действительна, но не рекомендуется по соображениям производительности), она работает. Но я не понимаю, почему это имеет значение, поскольку 156349 == 156349, как и 7 == 7.

Я совершенно сбит с толку и боюсь, что упускаю что-то очень очевидное и просто не вижу этого. Если это так, позор мне, но все же, я был бы признателен за подсказку: -)

Большое спасибо!

1 Ответ

9 голосов
/ 30 августа 2011

Это может произойти, если ваш Context объект изменчив, что влияет на хеш-код, и если вы выполнили операцию, которая изменяет хеш-код после , помещая его в карту. Карта будет записывать только значение hashCode() в точке вставки , а затем будет использовать его для поиска совпадений при попытке найти конкретный ключ.

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

Конечно, это всего лишь предположение, но оно соответствует симптомам.

...