我已经运行了以下程序
public static void main(String... args) throws IllegalAccessException, NoSuchFieldException {
for (int i = 12; i < 80; i++) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>((int) Math.ceil(i / 0.75));
int beforeAdding = Array.getLength(getField(map, "table"));
for (int j = 0; j < i; j++) map.put(j, j);
int afterAdding = Array.getLength(getField(map, "table"));
map.put(i, i);
int oneMore = Array.getLength(getField(map, "table"));
System.out.printf("%,d: initial %,d, after N %,d, after N+1 %,d%n ",
i, beforeAdding, afterAdding, oneMore);
}
}
private static <T> T getField(Map<Integer, Integer> map, String fieldName) throws NoSuchFieldException, IllegalAccessException {
Field table = map.getClass().getDeclaredField(fieldName);
table.setAccessible(true);
return (T) table.get(map);
}
打印输出
12: initial 16, after N 16, after N+1 32
13: initial 32, after N 32, after N+1 32
.. deleted ..
24: initial 32, after N 32, after N+1 64
25: initial 64, after N 64, after N+1 64
.. deleted ..
47: initial 64, after N 64, after N+1 64
48: initial 64, after N 64, after N+1 128
49: initial 128, after N 128, after N+1 128
.. deleted ..
79: initial 128, after N 128, after N+1 128
这表明默认初始化器的初始容量会被舍入到下一个二次幂。这个值的问题在于,如果你希望这是最终大小,你必须考虑负载因子,以避免调整大小。理想情况下,你不应该这样做,就像 Map 的复制构造函数为你所做的那样。