JDK LinkedHashMap源码解析

本文深入剖析了JDK中LinkedHashMap的源代码,探讨了其继承自HashMap的特点及其实现方式,重点介绍了迭代顺序控制机制及LRU算法的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天来分析一下JDK  LinkedHashMap的源代码

 

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

 可以看到,LinkedHashMap继承自HashMap,并且也实现了Map接口,所以LinkedHashMap沿用了HashMap的大多数方法

,包括构造方法也调用了父类HashMap的构造方法:

 

public LinkedHashMap(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor);
        accessOrder = false;
    }

   
    public LinkedHashMap(int initialCapacity) {
	super(initialCapacity);
        accessOrder = false;
    }

   
    public LinkedHashMap() {
	super();
        accessOrder = false;
    }

   
    public LinkedHashMap(Map<? extends K, ? extends V> m) {
        super(m);
        accessOrder = false;
    }

   
    public LinkedHashMap(int initialCapacity,
			 float loadFactor,
                         boolean accessOrder) {
        super(initialCapacity, loadFactor);
        this.accessOrder = accessOrder;
    }

 但是昨天在分析HashMap的时候说过HashMap的init方法没有实现,但是LinkedHaqshMap已经对其实现:

 

void init() {
        header = new Entry<K,V>(-1, null, null, null);//初始化一个Entry类型的header
        header.before = header.after = header;
    }

 在LinkedHashMap中多了一个accessOrder变量,他表示迭代时候的一个顺序,若为true,则按照读取顺序排序(读得越多越在前,也就最先被迭代),若为false

则按照插入顺序排序.从LinkedHaqshMap的前4个构造方法可以看出,accessOrder默认为false,故按照插入顺序进行排序.

 

 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;
    }

 

 在这个get方法中要注意recordAccess这个方法:

 

 void recordAccess(HashMap<K,V> m) {
            LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;
            if (lm.accessOrder) {
                lm.modCount++;
                remove();
                addBefore(lm.header);
            }
        }

 这个方法定义在LinkedHashMap的内部类Entry中,他判断accessOrder属性,若为true,则执行一个叫做LRU的算法

该算法的中文名称叫做最近最少使用算法,他通过将刚访问的entry移除,然后加到header前面,这样迭代的时候会优先迭代

最近频繁访问的entry,从而就改变了迭代的顺序

对于put方法,LinkedHashMap也实现了父类HashMap没有实现的recordAccess,并重写了addEntry方法,虽然在LinkedHashMap没有重写put方法

 

void addEntry(int hash, K key, V value, int bucketIndex) {
        createEntry(hash, key, value, bucketIndex);//在header前构造一个entry
    
        Entry<K,V> eldest = header.after;//找到最老的一个元素
        if (removeEldestEntry(eldest)) {
            removeEntryForKey(eldest.key);
        } else {
            if (size >= threshold)
                resize(2 * table.length);
        }
    }

 可以看到该方法会删除最老的一个元素,removeEldestEntry是一个受保护的方法,用来确定是否满足删除条件,可以重写它实现自己的策略,默认该方法返回false

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值