其中:
size表示了map中的键值对个数
/**
* The number of key-value mappings contained in this map.
*/
transient int size;
loadFactor表示装载因子,用来衡量HashMap满的程度。loadFactor的默认值为0.75f。
/**
* The load factor for the hash table.
*
* @serial
*/
final float loadFactor;
threshold:临界值,当实际KV个数超过threshold时,HashMap会将容量扩容,threshold=容量*装载因子
/**
* The next size value at which to resize (capacity * load factor).
*
* @serial
*/
// (The javadoc description is true upon serialization.
// Additionally, if the table array has not been allocated, this
// field holds the initial array capacity, or zero signifying
// DEFAULT_INITIAL_CAPACITY.)
int threshold;
capacity容量:默认最小容量是16.
/**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
如下所示测试代码,测试map的size和capacity
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
HashMap<String, String> map = new HashMap<String, String>();
map.put("test", "123");
Class mapD = map.getClass();
Method method = mapD.getDeclaredMethod("capacity");
method.setAccessible(true);
System.out.println("capacity=" + method.invoke(map));
System.out.println("size=" + map.size());
}
输出:
因此capaticty: 表示最多能装多少;size:表示已经装了多少。为什么初始化容量设置成16,因为按位运算快。
也可以在初始化的时候,指定map容量大小,会默认找到比他大且离他最近的一个2的n次方。如下:
HashMap<String, String> map = new HashMap<String, String>(7);
Class mapD = map.getClass();
Method method = mapD.getDeclaredMethod("capacity");
method.setAccessible(true);
System.out.println("capacity=" + method.invoke(map));
System.out.println("size=" + map.size());
输出:
初始化指定的是9的化,输出就是16.
当HashMap中的元素个数(size)超过临界值(threshold)时就会自动扩容。
HashMap<String, String> map = new HashMap<String, String>(7);
Class mapD = map.getClass();
Method method = mapD.getDeclaredMethod("capacity");
method.setAccessible(true);
System.out.println("before capacity=" + method.invoke(map));
System.out.println("before size=" + map.size());
System.out.println("===============================================");
map.put("test1", "123");
map.put("test2", "123");
map.put("test3", "123");
map.put("test4", "123");
map.put("test5", "123");
map.put("test6", "123");
map.put("test7", "123");
System.out.println("After capacity=" + method.invoke(map));
System.out.println("After size=" + map.size());
输出结果为:
触发扩容时机:
当map的size > capacity * 0.75 就会触发扩容。上面例子,就是 size > 8*0.75 (loadFactor乘capacity),就会触发扩容,容量变为16。loadFactor乘capacity也就是阈值。
Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入,通过散列算法,变换成固定长度的输出,该输出就是散列值。
hashMap数据结构