我有一个以下课程
public class Animal {
private int hash;
public Animal(int hash) {
this.hash = hash;
}
@Override
public int hashCode() {
System.out.println(hash);
return hash;
}
}
和此代码
public static void main(String[] args) {
Map<Animal, Integer> map = new HashMap<>();
for (int i = 0; i < 4; i++) {
map.put(new Animal(16 * i), i);
}
Animal an = new Animal(16*4);
map.put(an, 1);
for (int i = 5; i < 9; i++) {
map.put(new Animal(16 * i), i);
}
Integer value = map.get(an);
}
据我了解,所有这些值都应放在一个存储桶中(由于其哈希码)。在最后一次调用map.get(an)
时,hashCode()仅被调用一次(根据控制台),但是在通过存储桶进行迭代并使用正确的hashCode()查找条目时,不应多次调用hashCode()吗?
我有一个以下类,公共类Animal {private int hash; public Animal(int hash){this.hash = hash; } @Override public int hashCode(){System.out ....
单个存储桶可能包含具有不同hashCode
的键,并且将相关存储桶的键hashCode
与您要添加/搜索的键进行比较。但是,hashCode
缓存在Map.Entry
中,因此无需为hashCode
中已经存在的Entry
调用键的Map
方法:
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node<K,V> next;
Node(int hash, K key, V value, Node<K,V> next) {
this.hash = hash; // here the hash code is cached
this.key = key;
this.value = value;
this.next = next;
}
...
}
否,哈希码用于查找存储桶,这需要对hashcode
的单个调用(在map.get(an)
的参数上调用)。
最多您可以期望hashCode()
被完全调用。调用次数是HashMap
的实现详细信息,您不应期望任何特定行为,也不应观察到行为是稳定的。由于hashCode()
可以以不同的方式实现,甚至成本很高,因此仅调用一次是一个合理的选择,即使需要多次调用,也要使用返回值代替对hashCode()
的新调用。但是,这仅是一种猜测,因此不应假定。
每个人都已经回答了问题。我想从HashMap捕获代码以提供更多信息
确定存储桶后,HashMap
将使用。eqauls
确定与提供的对象匹配的链表节点。查看实现: