浅谈LinkedHashMap

LinkedHashMap

底层使用的是HashMap, 包括新加元素,只是重写了部分方法,就实现了双向链表的维护

数据结构

LinkedHashMap中,使用Entry作为节点,Entry继承HashMap中的Node 并添加了两个成员变量before after来单独维护遍历顺序(并不一定是插入顺序),并在LinkedHashMap中重写了newNode()方法
LinkedHashMap存储数据的结构

添加元素执行过程

LinkedHashMap的添加方法直接使用了父类HashMap的方法
HashMap添加元素时,一种是新增节点,一种是修改节点,其中新增节点基本都是通过newNode()实现的 如:

if ((p = tab[i = (n - 1) & hash]) == null)
    tab[i] = newNode(hash, key, value, null);
if ((e = p.next) == null) {
    p.next = newNode(hash, key, value, null);
    if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
        treeifyBin(tab, hash);
    break;
}

LinkedHashMap重写了父类的NewNode()方法

Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {
    LinkedHashMap.Entry<K,V> p =
        new LinkedHashMap.Entry<K,V>(hash, key, value, e); 
    //以上部分与HashMap一样,只不过改了一下调用方式
    linkNodeLast(p); //唯一的区别
    return p;
}

在这里维护遍历顺序

// link at the end of list
private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
    LinkedHashMap.Entry<K,V> last = tail; //新建尾结点
    tail = p; //更新尾指针
    if (last == null) //如果位置真为null 表示这是第一个节点,那么给头指针赋值
        head = p;
    //维护链表
    else {
        p.before = last;
        last.after = p;
    }
}

通过重写NewNode(),完成了对HashMap的拓展,又没有修改putVal(),这样实现了无代码入侵的增强。

实现LRU算法

LRU(Least Recently Used) 即最近最少使用,是一种缓存淘汰策略。在缓存满了的时候,会将那些最近最不常访问的数据删除

LinkedHashMap 除了可以维护插入顺序,还可以维护访问顺序,只要在初始化时,将accessIrder设为true

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

那么,在访问一个节点后,LinkeHashMap会将该元素移动到链表的尾部,那么链表的头部就是最近最不常访问的元素,当缓存满了之后,就可以把头部元素删除

Java中已经有了对应的实现类LRUCache

public class LRUCache<K, V> extends LinkedHashMap<K, V> {
    private static final long serialVersionUID = 1L;
    protected int maxElements;

	//调用LinkedHashMap的构造方法,并固定最大容量
    public LRUCache(int maxSize) {
        super(maxSize, 0.75F, true);
        this.maxElements = maxSize;
    }

    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        return this.size() > this.maxElements;
    }
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值