HashMap源码阅读与解析

二、HashMap构造方法以及存储结构

三、put()方法解析

四、addEntry()方法解析

五、get()方法解析

六、remove()方法解析

七、HashMap遍历

目录结构

导入语

HashMap构造方法

put()方法解析

addEntry()方法解析

get()方法解析

remove()解析

HashMap如何进行遍历

一、导入语

HashMap是我们最常见也是最长使用的数据结构之一,它的功能强大、用处广泛。而且也是面试常见的考查知识点。常见问题可能有HashMap存储结构是什么样的?HashMap如何放入键值对、如何获取键值对应的值以及如何删除一个键值对。今天我们就来看看HashMap底层的实现原理。下面我们就开始进入正题,分析一下hashmap源码的实现原理。

二、HashMap构造方法以及存储结构

public HashMap() { this.loadFactor = DEFAULT_LOAD_FACTOR; threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR); table = new Entry[DEFAULT_INITIAL_CAPACITY]; init(); }

HashMap的构造方法有好几个,在这里我们就不一一介绍,只说一下我们最常见的HashMap无参构造方法。上面的构造方法中,有几个变量需要我们这里说明一下:

loadFactor:加载因子,默认值为0.75;

threshold:threshold是一个阈值,初始值为默认为16*0.75。当hashmap中存放键值对数量大于该值时,表示hashmap容量大小需要扩充,一般容量会翻倍。

table:table其实是一个Entry类型的数组,在hashmap中我们利用数组和链表来解决hash冲突,这里的table数组用于存放冲突链表的头结点。

另外在HahsMap中,我们通过数组加链表的方式来存储Entry节点(Entry数据结构用于存储键值对)。这里所谓的数组即是上面提到的table,它是一个Entry数组,table对象中节点初始化值均为null,当我们新插入的节点第一次散列到该位置时,会将节点插入到table中对应位置。如果后续存在散列位置相同的节点,会以链表的方式解决hash冲突。示意图如下:

HashMap源码阅读与解析

三、put()方法解析

put方法是我们最常用方法,我们利用该方法将键值对放入HashMap集合中,那么HashMap到底是什么样的结构,put()方法又做了什么呢?我们下面就来看看put()方法的具体实现。

public V put(K key, V value) { if (key == null) return putForNullKey(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; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; } private V putForNullKey(V value) { for (Entry<K,V> e = table[0]; e != null; e = e.next) { if (e.key == null) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(0, null, value, 0); return null; }

if (key == null) return putForNullKey(value);

如果当前传入的key值为null,执行putForNullKey()方法;当key值为null时,hash值为0,将其保存到以table[0]为开头的链表中去。遍历链表,如果存在某节点的key值为null,则用新value直接将其替换。如果未找到key值为null的节点,调用addEntry()方法插入一个key为null的新节点。addEntry方法我们会在后文中介绍。

int hash = hash(key.hashCode()); int i = indexFor(hash, table.length);

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/f8ec0a8aae75abc6c4d1eda9203d2da7.html