hashmap是一个键值对的无序数组。经过hashcode指引内存地址获取值。
hashmap不是有序数组,也不是散列链表,他能够理解为一个无序的数组,经过hashcode去映射。数组
hashmap在第一次put的时候,会初始化键值对数组的大小16,加载因子0.75,当数组超过16*0.75=12的时候,数组会扩容2倍。this
hashmap的put方法源码
public V put(K key, V value) {
if (table == EMPTY_TABLE) {
//若是第一次加载,判断是空数组,初始化大小16
inflateTable(threshold);
}
if (key == null)
//hashmap支持null键,经过单独的方法put
return putForNullKey(value);
//获取key的hashcode,若是有就替换旧的value
int hash = hash(key);
//获取hashcode在数组中的索引
int i = indexFor(hash, table.length);
//
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
//若是当前索引有value,就替换
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
//将新value放到e.v中
e.value = value;
//没任何实现,是个空方法
e.recordAccess(this);
return oldValue;
}
}
//结构性更改次数加1
modCount++;
//添加新元素
addEntry(hash, key, value, i);
return null;
}code
//添加元素方法 void addEntry(int hash, K key, V value, int bucketIndex) { threshold就是16*0.75,当map在使用75%时候会扩容 if ((size >= threshold) && (null != table[bucketIndex])) { resize(2 * table.length); hash = (null != key) ? hash(key) : 0; bucketIndex = indexFor(hash, table.length); } //添加元素 createEntry(hash, key, value, bucketIndex); }
hashmap get方法;
public V get(Object key) {
if (key == null)
return getForNullKey();
Entry<K,V> entry = getEntry(key);索引
return null == entry ? null : entry.getValue(); } //获取hashcode,直接获取值,效率高 final Entry<K,V> getEntry(Object key) { if (size == 0) { return null; } int hash = (key == null) ? 0 : hash(key); for (Entry<K,V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) return e; } return null; }