共计 1923 个字符,预计需要花费 5 分钟才能阅读完成。
LinkedHashMap 是 HashMap 的子类,上一节初步剖析过 HashMap,这一节剖析 LinkedHashMap。
LinkedHashMap 的数据结构
Entry
LinkedHashMap 的 Entry 继承自 HashMap 的 Node,除了 Node 的数据结构之外,减少了 before、after,所以咱们能够猜测到 LinkedHashMap 的 Entry 应该是双向列表构造:
static class Entry<K,V> extends HashMap.Node<K,V> {
Entry<K,V> before, after;
Entry(int hash, K key, V value, Node<K,V> next) {super(hash, key, value, next);
}
}
此外,LinkedHashMap 定义了首节点和尾结点:
transient LinkedHashMap.Entry<K,V> head;
/**
* The tail (youngest) of the doubly linked list.
*/
transient LinkedHashMap.Entry<K,V> tail;
table 数组
继承自 HashMap, 没有变动!
数据仍然保留在 table 数组中,不同的是 table 中的对象变成了 Entry。
LinkedHashMap 的初始化
与 HashMap 的初始化形式、以及波及到的容量、装载因子、扩容阈值等概念基本相同。
不过,减少了一个概念 accessOrder,javadoc 的解释是定义遍历拜访程序,当值为 true 时依照拜访程序排序,值为 false 则依照插入程序排序。
/**
* The iteration ordering method for this linked hash map: <tt>true</tt>
* for access-order, <tt>false</tt> for insertion-order.
*
* @serial
*/
final boolean accessOrder;
LinkedHashMap 赋值
LinkedHashMap 的赋值逻辑如下(假如待寄存的数据为 e <key1,value1>):
- 查看 table 数组为空的话,初始化指定容量或者默认容量的 table 数组
- 依据 key1 的哈希值计算得出(算法为(容量 – 1)& hash(key1))对应的桶。这一步很重要,一般来讲优良的 hash 算法可能尽可能确保不同的 key 值得到不同的 hash 值,也就能够确保放入不同的桶内。然而不可避免的,可能会存在不同 key 值得到雷同 hash 值的状况(hash 抵触:key1<>key2,hash(key1)=hash(key2)),这种状况下就会搁置在雷同的桶(比方 table[5])内。
- 失去桶之后,判断桶内是否曾经有数据。
- 没有数据则间接新建一个 Node:newNode(hash, key1, value1, null),放在桶中,完结
- LinkedHashMap 新建的 Node 是他的 Entry 对象,所以创建对象的过程与 HashMap 的略有不同:创立的是双向链表(通过 before、after 首尾相连),并在创立的过程中指定 LinkedHashMap 的 head 和 tail。
- 否则,桶内有数据,有两种状况:一是为键值 key1 反复赋值、二是 hash 抵触。
- 如果是 hash 抵触,则 new 一个 Node:newNode(hash, key1, value1, null)并将其设置为桶内的最初一个 Node。
- 如果是反复赋值(桶内数据的 key 值 =key1),则为 key1 从新赋值 value1,并返回 key1 的旧值
与 HashMap 的赋值过程基本相同,不同之处在于:除了将数据调配在 hash 桶之外,同时依照存储数据的先后顺序创立双向链表。
从 LinkedHashMap 获取数据
LinkedHashMap 通过 key 值获取数据的逻辑与 HashMap 的完全一致
通过 get(key)办法获取数据的逻辑如下(假如要获取的数据 key=key1):
- table 数组不为空并且数组长度大于 0,则采纳与 put 数据雷同的算法失去 key1 值对应的桶。
- 桶内不空则从第一个节点开始查看,如果节点 key 值等于 key1,则返回该节点的 value。如果第一个节点不满足条件,则顺次查看桶内所有其余节点。
- 桶内空,或者桶内不空然而没有找到满足条件的对象(应该不可能)则返回 null,表明以后 HashMap 中不存在 key 值为 key1 的对象
所以咱们能够看到,正如名称给咱们的启发一样,LinkedHashMap 与 HashMap 的区别就是多了一个链表
大家晓得 LinkedHashMap 可能确保依照存储程序获取数据,而 HashMap 遍历到的数据是随机的,下次咱们就具体分析一下其底层起因。