LinkedHashMap源码详解
LinkedHashMap是基于HashMap实现的,如果对HashMap不了解,请先学习HashMap:http://blog.csdn.net/luanmousheng/article/details/75195809
HashMap的无序性和LinkedHashMap的有序性
前面介绍的HashMap查找效率很高,但是也有一个缺点,即遍历HashMap是无序的。LinkedHashMap顾名思义,是链表和哈希表的结合,链表具有天然的有序性,这里的有序不是按照节点大小排序,而是按照节点的插入顺序排序或者节点的访问顺序排序。
为了比较HashMap和LinkedHashMap的有序性,首先观察HashMap的遍历结果:
Map<String, String> map2 = new HashMap();
map2.put("name", "jack");
map2.put("age", "23");
map2.put("job", "student");
map2.put("home", "china");
Iterator<Map.Entry<String, String>> it2 = map2.entrySet().iterator();
while(it2.hasNext()) {
System.out.println(it2.next().getKey());
}
这段代码段输出:
home
age
name
job
可以看到,遍历HashMap时的输出和输入时的顺序没有关系。
再观察LinkedHashMap的遍历结果:
LinkedHashMap<String, String> map = new LinkedHashMap();
map.put("name", "jack");
map.put("home", "china");
map.put("age", "23");
map.put("job", "student");
Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
while(it.hasNext()) {
System.out.println(it.next().getKey());
}
这段代码输出:
name
home
age
job
可以看到,默认情况下,遍历LinkedHashMap时的输出和输入的顺序是一致的。因此我们说LinkedHashMap是可以保证有序性的。
我们说默认情况下,遍历LinkedHashMap时的输出和输入的顺序是一致的,LinkedHashMap还可以根据节点的访问顺序进行排序,即最新访问的节点放在最前面。LinkedHashMap提供了accessOrder字段,这个字段可以指示LinkedHashMap是否按照访问时间进行排序,通过LinkedHashMap另一个带参数的构造函数可以创建一个按照访问时间排序的哈希表,看下面的例子:
LinkedHashMap<String, String> map = new LinkedHashMap(10, 0.75F, true);
map.put("name", "jack");
map.put("home", "china");
map.put("age", "23");
map.put("job", "student");
//访问了键"home"的节点
map.get("home");
Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
while(it.hasNext()) {
System.out.println(it.next().getKey());
}
将4个键值对添加到LinkedHashMap后,访问了键”home”的节点,这段代码的输出为:
name
age
job
home
可以看到,键”home”被我们访问后,放到了最后一个位置(最新的位置),这就是LinkedHashMap按照访问先后顺序的有序性。
好了,对于LinkedHashMap有了基本的认识后,下面将基于源码,详细介绍LinkedHashMap的原理。
LinkedHashMap原理
LinkedHashMap的存储还是通过HashMap实现的,但是它和HashMap最大的区别在于LinkedHashMap维护了一个双向链表,这个双向链表按照节点的插入顺序保存节点、或者按照节点的访问先后顺序保存节点。
先看下LinkedHashMap的声明:
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> {
//……
private static class Entry<