HashMap ( jdk 1.6 ) 中的方法 "transfer " 有问题吗?

A matter in the method "transfer " in HashMap ( jdk 1.6 )?

源码是这样的:

void transfer(Entry[] newTable) {
    Entry[] src = table;
    int newCapacity = newTable.length;
    for (int j = 0; j < src.length; j++) {
        Entry<K,V> e = src[j];
        if (e != null) {
            src[j] = null;
            do {
                Entry<K,V> next = e.next;
                int i = indexFor(e.hash, newCapacity);
                e.next = newTable[i];
                newTable[i] = e;
                e = next;
            } while (e != null);
        }
    }
}

但是我想这样做,效果好还是有什么问题? 我认为同一个列表中所有元素的哈希值都是相同的,所以我们不需要计算新的table的buketIndex;我们唯一应该做的是 将 head 元素转移到新的 table,这将节省时间。 谢谢你的回答。

void transfer(Entry[] newTable){
    Entry[] src = table;
    int newCapacity = newTable.length;
    for(int j = 0 ;j< src.length;j++){
        Entry<K,V> e = src[j];
        if(null != e){
            src[j] = null;
            int i = indexFor(e.hash,newCapacity);
            newTable[i] = e;
        }
    }
}

我认为您是在询问 Java 6 中实现的 HashMap class,以及(特别是)您优化内部 transfer() 方法的想法是否会工作。

答案是否定的。

transfer方法在调整主数组大小时调用,其目的是将所有现有的散列条目转移到调整大小后的table中正确的散列链。您的代码只是在移动整个链条。那行不通的。问题在于哈希链通常包含具有多个不同哈希码的条目。虽然给定的一组条目在旧版本 table 中都属于同一条链,但在新版本中它们可能不会。

简而言之,您提议的修改将 "lose" 一些条目,因为它们在调整后的大小 table 中会位于错误的位置。


对此也有元答案。标准 Java classes 是由一群非常聪明的软件工程师编写和测试的。从那时起,该代码可能已被 Sun/Oracle 以外的数万或数十万其他聪明人阅读。 其他人 错过像这样简单/明显的优化的可能性是......微乎其微。

因此,如果您 在 Java SE 的 Java 源代码中找到您认为像是优化(或错误)的东西,你可能误会了!