我只問java版本的問題,直到1.7。我正在使用反射來查找HashMap的當前容量。在下面的程序中,將12個獨特的人放入一個HashMap桶中(使用相同的哈希碼)。然後,我將第13個唯一的人放在同一個或不同的存儲桶中(使用相同或不同的哈希碼)。在添加第13個元素後的兩種情況下,HashMap調整爲32個桶。我明白,由於負載因素.75和初始容量16 HashMap調整到它是第13個元素的雙倍。但是仍然有空的桶可用,並且這些第13個元素僅使用2個桶。爲什麼HashMap調整大小在發生衝突或最壞情況下
我的問題是:
1)我的理解是否正確。我沒有犯任何錯誤。這是HashMap的預期行爲。 2)如果所有這些都是正確的,那麼即使有12個或11個空閒桶,爲什麼在這種情況下需要使用第13個元素來加倍HashMap。調整HashMap的大小不是額外的開銷或昂貴的代價。在這種情況下需要將HashMap加倍,而根據哈希碼可以將第13個放入任何可用的桶中。
public class HashMapTest {
public static void main(String[] args) throws NoSuchFieldException,
SecurityException, IllegalArgumentException, IllegalAccessException {
HashMap<Person, String> hm = new HashMap<Person, String>();
for (int i = 1; i <= 12; i++) {
// 12 Entry in same bucket(linkedlist)
hm.put(new Person(), "1");
}
System.out.println("Number of Buckets in HashMap : "+bucketCount(hm));
System.out.println("Number of Entry in HashMap : " + hm.size());
System.out.println("**********************************");
// 13th element in different bucket
hm.put(new Person(2), "2");
System.out.println("Number of Buckets in HashMap : "+bucketCount(hm));
System.out.println("Number of Entry in HashMap : " + hm.size());
}
public static int bucketCount(HashMap<Person, String> h)
throws NoSuchFieldException, SecurityException,
IllegalArgumentException, IllegalAccessException {
Field tableField = HashMap.class.getDeclaredField("table");
tableField.setAccessible(true);
Object[] table = (Object[]) tableField.get(h);
return table == null ? 0 : table.length;
}
}
class Person {
int age = 0;
Person() {
}
Person(int a) {
age = a;
}
@Override
public boolean equals(Object obj) {
return false;
}
@Override
public int hashCode() {
if (age != 0) {
return 1;
} else {
return age;
}
}
}
輸出
Number of Buckets in HashMap : 16
Number of Entry in HashMap : 12
**********************************
Number of Buckets in HashMap : 32
Number of Entry in HashMap : 13
@Am_I_Helpful對於第二個答案,加載因子適用於輸入計數。爲什麼它看不到已經存在的桶。爲什麼它會調整性能。 –