LinkedHashMap
LinkedHashMap的结构如下图:
LinkedHashMap的使用
HashMap是无序的,当我们需要有序存储Key-value时就需要用LinkedHashMap
Map<String, String> hashMap = new HashMap<String, String>();
hashMap.put("name1", "Masssa1");
hashMap.put("name2", "Masssa2");
hashMap.put("name3", "Masssa3");
Set<Entry<String, String>> set = hashMap.entrySet();
Iterator<Entry<String, String>> iterator = set.iterator();
while(iterator.hasNext()) {
Entry entry = iterator.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
System.out.println("key:" + key + ",value:" + value);
}
/*输出
key:name3,value:Masssa3
key:name1,value:Masssa1
key:name2,value:Masssa2
*/
Map<String, String> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("name1", "Masssa1");
linkedHashMap.put("name2", "Masssa2");
linkedHashMap.put("name3", "Masssa3");
Set<Entry<String, String>> set = linkedHashMap.entrySet();
Iterator<Entry<String, String>> iterator = set.iterator();
while(iterator.hasNext()) {
Entry entry = iterator.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
System.out.println("key:" + key + ",value:" + value);
}
/*输出
key:name1,value:Masssa1
key:name2,value:Masssa2
key:name3,value:Masssa3
*/
可以看出LinkedHashMap的存储是按插入顺序排序的。
定义
LinkedHashMap继承了HashMap,所以他们大部分相似
public class LinkedHashMap<k,v>
extends HashMap<K,V>
implements Map<k,v>
构造方法
LinkedHashMap提供了多个构造方法,我们先看空参的构造方法。
public LinkedHashMap() {
// 调用HashMap的构造方法,其实就是初始化Entry[] table
//其默认初始容量(16)和负载因子(0.75)
super();
//
// 这里是指是否基于访问排序,默认为false
accessOrder = false;
}
accessOrder设置为false,这就跟存储的顺序有关了,LinkedHashMap存储数据是有序的,而且分为两种:插入顺序和访问顺序。这里accessOrder设置为false,表示不是访问顺序而是插入顺序存储的,这也是默认值,表示LinkedHashMap中存储的顺序是按照调用put方法插入的顺序进行排序的。LinkedHashMap也提供了可以设置accessOrder的构造方法,我们来看看这种模式下,它的顺序有什么特点?
// 第三个参数用于指定accessOrder值
Map<String, String> linkedHashMap = new LinkedHashMap<>(16, 0.75f, true);
linkedHashMap.put("name1", "masssa1");
linkedHashMap.put("name2", "masssa2");
linkedHashMap.put("name3", "masssa3");
System.out.println("开始时顺序:");
Set<Entry<String, String>> set = linkedHashMap.entrySet();
Iterator<Entry<String, String>> iterator = set.iterator();
while(iterator.hasNext()) {
Entry entry = iterator.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
System.out.println("key:" + key + ",value:" + value);
}
/*
输出
key:name1,value:Masssa1
key:name2,value:Masssa2
key:name3,value:Masssa3
*/
System.out.println("通过get方法,导致key为name1对应的Entry到表尾");
linkedHashMap.get("name1");
Set<Entry<String, String>> set2 = linkedHashMap.entrySet();
Iterator<Entry<String, String>> iterator2 = set2.iterator();
while(iterator2.hasNext()) {
Entry entry = iterator2.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
System.out.println("key:" + key + ",value:" + value);
}
/*
通过get方法,导致key为name1对应的Entry到表尾
key:name2,value:Masssa2
key:name3,value:Masssa3
key:name1,value:Masssa1
*/
使用按访问有序实现缓存
class LRUCache extends LinkedHashMap<Integer, Integer>{
private int capacity;
public LRUCache(int capacity) {
super(capacity, 0.75F, true);
this.capacity = capacity;
}
public int get(int key) {
return super.getOrDefault(key, -1);
}
public void put(int key, int value) {
super.put(key, value);
}
@Override
protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
return size() > capacity;
}
}