关于java:认识LinkedHashMap

40次阅读

共计 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>):

  1. 查看 table 数组为空的话,初始化指定容量或者默认容量的 table 数组
  2. 依据 key1 的哈希值计算得出(算法为(容量 – 1)& hash(key1))对应的桶。这一步很重要,一般来讲优良的 hash 算法可能尽可能确保不同的 key 值得到不同的 hash 值,也就能够确保放入不同的桶内。然而不可避免的,可能会存在不同 key 值得到雷同 hash 值的状况(hash 抵触:key1<>key2,hash(key1)=hash(key2)),这种状况下就会搁置在雷同的桶(比方 table[5])内。
  3. 失去桶之后,判断桶内是否曾经有数据。
  4. 没有数据则间接新建一个 Node:newNode(hash, key1, value1, null),放在桶中,完结
  5. LinkedHashMap 新建的 Node 是他的 Entry 对象,所以创建对象的过程与 HashMap 的略有不同:创立的是双向链表(通过 before、after 首尾相连),并在创立的过程中指定 LinkedHashMap 的 head 和 tail。
  6. 否则,桶内有数据,有两种状况:一是为键值 key1 反复赋值、二是 hash 抵触。
  7. 如果是 hash 抵触,则 new 一个 Node:newNode(hash, key1, value1, null)并将其设置为桶内的最初一个 Node。
  8. 如果是反复赋值(桶内数据的 key 值 =key1),则为 key1 从新赋值 value1,并返回 key1 的旧值

与 HashMap 的赋值过程基本相同,不同之处在于:除了将数据调配在 hash 桶之外,同时依照存储数据的先后顺序创立双向链表。

从 LinkedHashMap 获取数据

LinkedHashMap 通过 key 值获取数据的逻辑与 HashMap 的完全一致

通过 get(key)办法获取数据的逻辑如下(假如要获取的数据 key=key1):

  1. table 数组不为空并且数组长度大于 0,则采纳与 put 数据雷同的算法失去 key1 值对应的桶。
  2. 桶内不空则从第一个节点开始查看,如果节点 key 值等于 key1,则返回该节点的 value。如果第一个节点不满足条件,则顺次查看桶内所有其余节点。
  3. 桶内空,或者桶内不空然而没有找到满足条件的对象(应该不可能)则返回 null,表明以后 HashMap 中不存在 key 值为 key1 的对象

所以咱们能够看到,正如名称给咱们的启发一样,LinkedHashMap 与 HashMap 的区别就是多了一个链表

大家晓得 LinkedHashMap 可能确保依照存储程序获取数据,而 HashMap 遍历到的数据是随机的,下次咱们就具体分析一下其底层起因。

正文完
 0