如果一个类A重写了hashCode方法,没有重写equals方法。假设有该类的一个不为null的对象a1,我们来看一下,a作为HashMap的key时,put方法和get方法存在哪些问题?
put方法
public V put(K key, V value) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
if (key == null)
return putForNullKey(value);
int hash = hash(key);
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
将a1通过put方法添加到,HashMap时,存在两种情况:
- 假设该HashMap中已经存在一个与a1相同的a2对象,此时因为A类没有重写equals方法,导致a1不equals a2,a1则会存储到HashMap中。这样导致HashMap有2个key相同的键值对。
- 假设该HashMap中不存在与a1相同对象,a1则会存储到HashMap中。
get方法
public V get(Object key) {
if (key == null)
return getForNullKey();
Entry<K,V> entry = getEntry(key);
return null == entry ? null : entry.getValue();
}
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;
}
若key为a1的键值对已经存储在HashMap中,通过与a1相同的a2对象调用get方法,通过getEntry方法源码,可以看出,因为A类没有重写equals方法将导致通过a2无法获得键值对。
网友评论