public V get(Object key) { Entry<K,V> e = (Entry<K,V>)getEntry(key); if (e == null) return null; //关键的就是这个方法 e.recordAccess(this); return e.value; } //这个方法在上面已经分析过了,如果accessOrder为true,那么就会用访问顺序。if条件下的语句会执行,作用就是将最近访问的元素放链表的末尾。 void recordAccess(HashMap<K,V> m) { LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m; if (lm.accessOrder) { lm.modCount++; remove(); addBefore(lm.header); } }
2.7、使用默认的插入顺序就不用多分析了,也就是上面这个if下的代码不生效,就会使用插入顺序。
三、验证LinkedHashMap的功能
注意、map是不能够只能拿到迭代器的,只能够拿到keySet().iterator(); 也就是说迭代器是不能够迭代map的,到时能够间接的使用迭代器。就比如先拿到key的迭代器,然后在通过key找到对应的value值,或者直接用values()方法,拿到所有的map的value。values()方法的底层也是使用的迭代器。
1、使用访问顺序,结果确实是如我们所预期那样
注意:如果使用for循环来遍历,肯定就不是这个结果了,原因是for循环是按照key值的顺序来查找的呀,从1到6,这里如果需要验证访问顺序,就必须使用迭代器,而map使用迭代器有两种方式,一种就是我上面所用的使values(),另一种是使用keySet().Iterator();自己可以尝试一下。
四、总结
1、知道LinkedHashMap的实现原理。
1.1、实现原理,跟HashMap一模一样。HashMap有的特性,LinkedHashMap基本上都有。
1.2、具体的存储实现,就看一开始的那两张图。虽然第二张画得比较乱,但是仔细去看,就能够弄懂其中的道理。
2、知道LinkedHashMap迭代的访问顺序和插入顺序
2.1、关键属性accessOrder
2.2、关键方法recordAccess
3、知道LinekdHashMap和HashMap的区别。
3.1、LinkedHashMap是HashMap的子类,实现的原理跟HashMap差不多,唯一的区别就是LinkedHashMap多了一个双向循环链表。
3.2、因为有双向循环列表,所以LinkedHashMap能够记录插入元素的顺序,而HashMap不能,
4、map使用迭代的两种方式,知道其内部是如何使用迭代器的。
keySet().iterator()
values()