Что происходит, когда Map Java содержит ключ (E e) в Java
я проверил исходный код:
public boolean containsKey(Object key) {
Iterator<Map.Entry<K,V>> i = entrySet().iterator();
if (key==null) {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (e.getKey()==null)
return true;
}
} else {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (key.equals(e.getKey()))
return true;
}
}
return false;
}
public boolean equals(Object obj) {
return (this == obj);
}
Исходя из исходного кода, он показывает, что был вызван только метод "equal ()", поэтому, если я хочу поместить пользовательский объект на карту, я мог бы только переопределить метод "equal ()". так что я сделал эксперимент, результат отрицательный... я должен переопределить оба "equals ()" и "hashCode()" . поэтому мой вопрос:
- почему оба метода (equals(),hashCode()) должны быть переопределены.
- внутренняя операция "==" вызывает метод "hashCode ()"?
2 ответа
Из API Object.equals: обычно необходимо переопределять метод hashCode всякий раз, когда этот метод переопределяется, чтобы поддерживать общий контракт для метода hashCode, в котором говорится, что равные объекты должны иметь одинаковые хеш-коды. Вы можете найти более подробное объяснение в "Эффективной Java". Элемент 9. Всегда переопределять hashCode, когда вы переопределяете equals.
Нет, нет, это просто сравнение указателей, как сравнение двух целых
Это AbstractMap
Реализация. HashMap
, который переопределяет это, реализует это следующим образом:
public boolean containsKey(Object key) {
return getEntry(key) != null;
}
final Entry<K,V> getEntry(Object key) {
if (size == 0) {
return null;
}
int hash = (key == null) ? 0 : hash(key);
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}
final int hash(Object k) {
int h = hashSeed;
if (0 != h && k instanceof String) {
return sun.misc.Hashing.stringHash32((String) k);
}
h ^= k.hashCode();
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
Как видите, это зависит от hashCode()
, Другие типы карт могут действительно не зависеть от переопределения этого метода.