如果哈希码被覆盖,使其仅返回常量,那么 Hashmap 键将如何表现?

The*_*ght 4 java hashmap hashcode

我有一个关于 Java 的小问题Hashmap。如果我重写hashCode该方法:

@Override
public int hashCode(){
  return 9;
}
Run Code Online (Sandbox Code Playgroud)

这将导致所有HashMap键具有相同的索引。它们是否会被放置在映射中的链表结构中,或者映射是否仅包含替换了所有其他键的最后一个键?

Era*_*ran 5

它们将被放置在映射中的链表结构中,假设您没有重写该equals方法以始终返回 true。不同的key可能有相同的hashCode,但是如果所有的key都有相同的hashCode,那么你的HashMap就会变成一个链表,这就违背了使用这个结构的初衷。

您可以在实现中亲自看到它HashMap

/**
 * Associates the specified value with the specified key in this map.
 * If the map previously contained a mapping for the key, the old
 * value is replaced.
 *
 * @param key key with which the specified value is to be associated
 * @param value value to be associated with the specified key
 * @return the previous value associated with <tt>key</tt>, or
 *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
 *         (A <tt>null</tt> return can also indicate that the map
 *         previously associated <tt>null</tt> with <tt>key</tt>.)
 */
public V put(K key, V value) {
    if (key == null)
        return putForNullKey(value);
    int hash = hash(key.hashCode()); // hash would always be the same if hashCode is constant
    int i = indexFor(hash, table.length); // i would always be the same if hashCode is constant
    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))) { // the key is searched using the
                                                                       // equals method
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }

    modCount++;
    addEntry(hash, key, value, i);
    return null;
}
Run Code Online (Sandbox Code Playgroud)

  • 在 Java 8 中情况不再如此,如果太多元素进入同一个存储桶,它将切换到使用红黑树。 (7认同)