Java基础知识_LinkedHashMap

一、LinkedHashMap剖析

LinkedHashMap数据结构图

 

 归纳总结出LinkedHashMap几点

  底层是散列表和双向链表

  允许为null,不同步

  插入顺序是有序的(底层链表致使有序)

  装载因子和初始容量对LinkedHashMap影响很大

同时也给我带了几个疑问

  access-ordered和insertion-ordered具体的使用和意思

  为什么说初始容量对遍历没有影响

 

1.1 LinkedHashMap的域

 

 继承HashMap的Node节点,它是双向链表,包含前置指针和后置指针

1.2 LinkedHashMap重写的方法

下面举例两个比较重要的

 

 这就印证了我们的LinkedHashMap的底层确实是散列表和双向链表

  在构建新节点的时候,构建的是LinkedHashMap.Entry不再是Node

 

 1.3 构造方法

可以发现LinkedHashMap有5个构造方法。

下面我们来看看构造方法的定义是怎么样的:

 1     public LinkedHashMap(int initialCapacity, float loadFactor) {
 2         super(initialCapacity, loadFactor);
 3         accessOrder = false;
 4     }
 5 
 6     /**
 7      * Constructs an empty insertion-ordered <tt>LinkedHashMap</tt> instance
 8      * with the specified initial capacity and a default load factor (0.75).
 9      *
10      * @param  initialCapacity the initial capacity
11      * @throws IllegalArgumentException if the initial capacity is negative
12      */
13     public LinkedHashMap(int initialCapacity) {
14         super(initialCapacity);
15         accessOrder = false;
16     }
17 
18     /**
19      * Constructs an empty insertion-ordered <tt>LinkedHashMap</tt> instance
20      * with the default initial capacity (16) and load factor (0.75).
21      */
22     public LinkedHashMap() {
23         super();
24         accessOrder = false;
25     }
26 
27     /**
28      * Constructs an insertion-ordered <tt>LinkedHashMap</tt> instance with
29      * the same mappings as the specified map.  The <tt>LinkedHashMap</tt>
30      * instance is created with a default load factor (0.75) and an initial
31      * capacity sufficient to hold the mappings in the specified map.
32      *
33      * @param  m the map whose mappings are to be placed in this map
34      * @throws NullPointerException if the specified map is null
35      */
36     public LinkedHashMap(Map<? extends K, ? extends V> m) {
37         super();
38         accessOrder = false;
39         putMapEntries(m, false);
40     }
41 
42     /**
43      * Constructs an empty <tt>LinkedHashMap</tt> instance with the
44      * specified initial capacity, load factor and ordering mode.
45      *
46      * @param  initialCapacity the initial capacity
47      * @param  loadFactor      the load factor
48      * @param  accessOrder     the ordering mode - <tt>true</tt> for
49      *         access-order, <tt>false</tt> for insertion-order
50      * @throws IllegalArgumentException if the initial capacity is negative
51      *         or the load factor is nonpositive
52      */
53     public LinkedHashMap(int initialCapacity,
54                          float loadFactor,
55                          boolean accessOrder) {
56         super(initialCapacity, loadFactor);
57         this.accessOrder = accessOrder;
58     }
59 
60 
61     /**
62      * Returns <tt>true</tt> if this map maps one or more keys to the
63      * specified value.
64      *
65      * @param value value whose presence in this map is to be tested
66      * @return <tt>true</tt> if this map maps one or more keys to the
67      *         specified value
68      */

从构造方法上我们可以知道的是:LinkedHashMap默认使用的是插入顺序

LinkedHashMap的put方法和HashMap是一样的。在创建节点的时候,调用的是LinkedHashMap重写的方法

 

 

1.5 get方法

 

 get方法也多了,判断是否为访问顺序

 

1.6 remove方法

对于remove方法,在linkedhashMap中也没有重写,它调用的还是父类的HashMap的remove方法,在LinkedHashMap中重写的是afterNodeRemoval(Node<K,V> e)这个方法

当然了,在remove的时候会涉及到上面重写的方法:

 

1.7 遍历的方法

Set<Map.Entry<K,V>> entrySet()是被重写的了

 

 

看到了这里,我们就知道为啥注释说:初始容量对遍历没有影响

因为它遍历的是LinkedHashMap内部维护的一个双向链表,而不是散列表(当然了,链表双向链表的元素都来源于散列表)

 

总结

LinkedHashMap比HashMap多了一个双向链表的维护,在数据结构而言它要复杂一些,阅读源码起来比较轻松一些,因为大多都由HashMap实现了..

1.HashMap对元素的遍历顺序跟Entry插入的顺序无关,而LinkedHashMap对元素的遍历顺序可以跟Entry<K,V>插入的顺序保持一致。

2.当LinkedHashMap处于Get获取顺序遍历模式下,当执行get() 操作时,会将对应的Entry<k,v>移到遍历的最后位置。

3.LinkedHashMap处于按插入顺序遍历的模式下,如果新插入的<key,value> 对应的key已经存在,对应的Entry在遍历顺序中的位置并不会改变。

4.除了遍历顺序外,其他特性HashMap和LinkedHashMap基本相同。

 

posted @ 2019-09-09 16:06  chyblogs  阅读(214)  评论(0)    收藏  举报