+关注继续查看

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
HashMap.Node<K,V>[] tab; HashMap.Node<K,V> p; int n, i;
// ①、数组 table 为 null 时，调用 resize 方法创建默认大小的数组
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
// ②、计算下标，如果该位置上没有值，则填充
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
}

public class LinkedHashMap<K,V>
extends HashMap<K,V>
implements Map<K,V>{}

static class Entry<K,V> extends HashMap.Node<K,V> {
Entry(int hash, K key, V value, HashMap.Node<K,V> next) {
super(hash, key, value, next);
}
}

## 01、插入顺序

Map<String, String> hashMap = new HashMap<>();
hashMap.put("沉", "沉默王二");
hashMap.put("默", "沉默王二");
hashMap.put("王", "沉默王二");
hashMap.put("二", "沉默王二");
hashMap.put(null, null);
for (String key : hashMap.keySet()) {
System.out.println(key + " : " + hashMap.get(key));
}

null : null

Map<String, String> linkedHashMap = new LinkedHashMap<>();
for (String key : linkedHashMap.keySet()) {
System.out.println(key + " : " + linkedHashMap.get(key));
}

null : null

null 在最后一位插入，在最后一位输出。

HashMap.Node<K,V> newNode(int hash, K key, V value, HashMap.Node<K,V> e) {
return p;
}

private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
tail = p;
if (last == null)
else {
p.before = last;
last.after = p;
}
}

02、访问顺序

LinkedHashMap 不仅能够维持插入顺序，还能够维持访问顺序。访问包括调用 get() 方法、remove() 方法和 put() 方法。

1

Map<String, String> linkedHashMap = new LinkedHashMap<>(16, .75f, true);
System.out.println(linkedHashMap);

{沉=沉默王二, 默=沉默王二, 王=沉默王二, 二=沉默王二}

{沉=沉默王二, 王=沉默王二, 二=沉默王二, 默=沉默王二}

{沉=沉默王二, 二=沉默王二, 默=沉默王二, 王=沉默王二}

public class MyLinkedHashMap<K, V> extends LinkedHashMap<K, V> {
private static final int MAX_ENTRIES = 5;
int initialCapacity, float loadFactor, boolean accessOrder) {
}
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > MAX_ENTRIES;
}
}

MyLinkedHashMap<String,String> map = new MyLinkedHashMap<>(16,0.75f,true);
map.put("沉", "沉默王二");
map.put("默", "沉默王二");
map.put("王", "沉默王二");
map.put("二", "沉默王二");
map.put("一枚有趣的程序员", "一枚有趣的程序员");
System.out.println(map);
map.put("一枚有颜值的程序员", "一枚有颜值的程序员");
System.out.println(map);
map.put("一枚有才华的程序员","一枚有才华的程序员");
System.out.println(map);

{沉=沉默王二, 默=沉默王二, 王=沉默王二, 二=沉默王二, 一枚有趣的程序员=一枚有趣的程序员}

{默=沉默王二, 王=沉默王二, 二=沉默王二, 一枚有趣的程序员=一枚有趣的程序员, 一枚有颜值的程序员=一枚有颜值的程序员}

{王=沉默王二, 二=沉默王二, 一枚有趣的程序员=一枚有趣的程序员, 一枚有颜值的程序员=一枚有颜值的程序员, 一枚有才华的程序员=一枚有才华的程序员}

MyLinkedHashMap<String,String> map = new MyLinkedHashMap<>(16,0.75f,true);
map.put("沉", "沉默王二");
map.put("默", "沉默王二");
map.put("王", "沉默王二");
map.put("二", "沉默王二");
map.put("一枚有趣的程序员", "一枚有趣的程序员");
System.out.println(map);
map.put("一枚有颜值的程序员", "一枚有颜值的程序员");
System.out.println(map);
map.get("默");
map.put("一枚有才华的程序员","一枚有才华的程序员");
System.out.println(map);

{沉=沉默王二, 默=沉默王二, 王=沉默王二, 二=沉默王二, 一枚有趣的程序员=一枚有趣的程序员}

{默=沉默王二, 王=沉默王二, 二=沉默王二, 一枚有趣的程序员=一枚有趣的程序员, 一枚有颜值的程序员=一枚有颜值的程序员}

{二=沉默王二, 一枚有趣的程序员=一枚有趣的程序员, 一枚有颜值的程序员=一枚有颜值的程序员, 默=沉默王二, 一枚有才华的程序员=一枚有才华的程序员}

void afterNodeAccess(Node<K,V> p) { }

void afterNodeInsertion(boolean evict) { }

void afterNodeRemoval(Node<K,V> p) { }

afterNodeAccess() 会在调用 get() 方法的时候被调用，afterNodeInsertion() 会在调用 put() 方法的时候被调用，afterNodeRemoval() 会在调用 remove() 方法的时候被调用。

void afterNodeAccess(HashMap.Node<K,V> e) { // move node to last
if (accessOrder && (last = tail) != e) {
(LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
p.after = null;
if (b == null)
else
b.after = a;
if (a != null)
a.before = b;
else
last = b;
if (last == null)
else {
p.before = last;
last.after = p;
}
tail = p;
++modCount;
}
}

MyLinkedHashMap<String,String> map = new MyLinkedHashMap<>(16,0.75f,true);
map.put("沉", "沉默王二");
map.put("默", "沉默王二");
map.put("王", "沉默王二");
map.put("二", "沉默王二");
map.put("一枚有趣的程序员", "一枚有趣的程序员");
System.out.println(map);
map.put("一枚有颜值的程序员", "一枚有颜值的程序员");
System.out.println(map);
map.get("默");
map.put("一枚有才华的程序员","一枚有才华的程序员");
System.out.println(map);

removeEldestEntry() 方法会判断第一个元素是否超出了可容纳的最大范围，如果超出，那就会调用 removeNode() 方法对最不经常访问的那个元素进行删除。

8919 0

11017 0

11673 0

10522 0

4446 0

6013 0
+关注

1084

0

《Nacos架构&原理》

《看见新力量：二》电子书