LinkedListMap介绍

前言

LinkedHashMap继承于HashMap

应用场景

HashMap是无序的,当我们希望有顺序地去存储key-value时,就需要使用LinkedHashMap了。

1
2
3
4
5
6
7
8
9
10
11
12
Map<String, String> hashMap = new HashMap<String, String>();
hashMap.put("name5", "value5");
hashMap.put("name6", "value6");
hashMap.put("name7", "value7");
Set<Map.Entry<String, String>> set = hashMap.entrySet();
Iterator<Map.Entry<String, String>> iterator = set.iterator();
while(iterator.hasNext()) {
Map.Entry entry = iterator.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
System.out.println("key:" + key + ",value:" + value);
}

输出结果

1
2
3
key:name6,value:value6
key:name5,value:value5
key:name7,value:value7

同样的数据,我们再试试LinkedHashMap

1
2
3
4
5
6
7
8
9
10
11
12
Map<String, String> hashMap = new LinkedHashMap<>();
hashMap.put("name5", "value5");
hashMap.put("name6", "value6");
hashMap.put("name7", "value7");
Set<Map.Entry<String, String>> set = hashMap.entrySet();
Iterator<Map.Entry<String, String>> iterator = set.iterator();
while(iterator.hasNext()) {
Map.Entry entry = iterator.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
System.out.println("key:" + key + ",value:" + value);
}

输出结果

1
2
3
key:name5,value:value5
key:name6,value:value6
key:name7,value:value7

LinkedHashMap是有序的,且默认为插入顺序。

LinkedHashMap空参的构造方法。

1
2
3
4
5
6
public LinkedHashMap() {
// 调用HashMap的构造方法
super();
// 这里是指是否基于访问排序,默认为false
accessOrder = false;
}

这里accessOrder设置为false,表示不是访问顺序而是插入顺序存储的,这也是默认值,表示LinkedHashMap中存储的顺序是按照调用put方法插入的顺序进行排序的。LinkedHashMap也提供了可以设置accessOrder的构造方法。

在HashMap的构造函数中,调用了init方法,而在HashMap中init方法是空实现,但LinkedHashMap重写了该方法,所以在LinkedHashMap的构造方法里,调用了自身的init方法,init的重写实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* Called by superclass constructors and pseudoconstructors (clone,
* readObject) before any entries are inserted into the map. Initializes
* the chain.
*/
@Override
void init() {
// 创建了一个hash=-1,key、value、next都为null的Entry
header = new Entry<>(-1, null, null, null);
// 让创建的Entry的before和after都指向自身,注意after不是之前提到的next
// 其实就是创建了一个只有头部节点的双向链表
header.before = header.after = header;
}

LinkedHashMap有自己的静态内部类Entry,它继承了HashMap.Node,定义如下:

1
2
3
4
5
6
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构造函数,主要就是调用HashMap构造函数初始化了一个Entry[] table,然后调用自身的init初始化了一个只有头结点的双向链表。

总结

LinkedHashMap 是继承于HashMap,是基于HashMap和双向链表来实现的。

HashMap无序;LinkedHashMap有序,可分为插入顺序和访问顺序两种。如果是访问顺序,那put和get操作已存在的Entry时,都会把Entry移动到双向链表的表尾(其实是先删除再插入)。

LinkedHashMap存取数据,还是跟HashMap一样使用的Entry[]的方式,双向链表只是为了保证顺序。

LinkedHashMap是线程不安全的。

-------------本文结束感谢您的阅读-------------