java系列-LinkedHashMap怎么实现LRU

news2024/11/23 6:33:59

 1.定义变量accessOrder

public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> {
    final boolean accessOrder;

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

2.最近访问的节点移动到链表末尾

 

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

    void afterNodeAccess(Node<K,V> e) { // move node to last
        LinkedHashMapEntry<K,V> last;
        if (accessOrder && (last = tail) != e) { //e不是tail
            LinkedHashMapEntry<K,V> p =
                (LinkedHashMapEntry<K,V>)e, b = p.before, a = p.after;
            p.after = null;
            if (b == null){ //原来p是head,p被移到最后,那head就变成p.after
                head = a;
            } else{
                b.after = a; //b  p  a 中间p被移走,b和a需要串起来
            }
            if (a != null){ //b  p  a 中间p被移走,b和a需要串起来
                a.before = b;
            } else{ //原来a为null,说明p为tail(这个场景不是不会走进来吗?)
                last = b;
            }
            if (last == null){ //last为null说明链表只有一个元素,更新head
                head = p;
            }else {
                p.before = last; //last  p
                last.after = p;
            }
            tail = p; //更新尾
            ++modCount;
        }
    }
}

3.LruCache

3.1.LruCache.put
public class LruCache<T, Y> {
    @Nullable
    public synchronized Y put(@NonNull T key, @Nullable Y item) {
        final int itemSize = getSize(item);
        if (itemSize >= maxSize) {
            onItemEvicted(key, item);
            return null;
        }

        if (item != null) {
            currentSize += itemSize;
        }

        @Nullable Entry<Y> old = cache.put(key, item == null ? null 
                                         : new Entry<>(item, itemSize));
        if (old != null) {
            currentSize -= old.size;

            if (!old.value.equals(item)) {
                onItemEvicted(key, old.value);
            }
        }
        evict(); //看放入之后,大小是否超过

        return old != null ? old.value : null;
    }
}
3.2.LruCache.evict
public class LruCache<T, Y> {
    private void evict() {
        trimToSize(maxSize);
    }
}
    
    
3.3.LruCache.trimToSize

循环移除,直到size小于maxSize,每次移除链表头元素

public class LruCache<T, Y> {

    protected synchronized void trimToSize(long size) {
        Map.Entry<T, Entry<Y>> last;
        Iterator<Map.Entry<T, Entry<Y>>> cacheIterator;
        while (currentSize > size) {
            cacheIterator = cache.entrySet().iterator(); //LinkedHashMap遍历
            last = cacheIterator.next(); //获取的是链表的第一个元素
            final Entry<Y> toRemove = last.getValue();
            currentSize -= toRemove.size; //更新移除后的size
            final T key = last.getKey();
            cacheIterator.remove();  //将元素移除
            onItemEvicted(key, toRemove.value);
        }
    }
}

3.4.LinkedHashIterator.remove

public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>{
    abstract class LinkedHashIterator {
        public final void remove() {
            Node<K,V> p = current;
            if (p == null){
                throw new IllegalStateException();
            }
            if (modCount != expectedModCount){
                throw new ConcurrentModificationException();
            }
            current = null;
            K key = p.key;
            removeNode(hash(key), key, null, false, false); //HashMap的移除方法
            expectedModCount = modCount;
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1306590.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小间距LED显示屏的芯片扮演的关键角色

LED屏幕由数万颗灯珠封装而成&#xff0c;包含驱动芯片、PCB板、电阻、电容、模组套件和箱体等&#xff0c;形成一块高清LED显示屏。芯片的质量直接影响整个屏幕的品质、稳定性和性能。那么&#xff0c;什么是细间距LED显示屏&#xff1f;小间距LED显示屏芯片具体有何作用呢&am…

设计模式(2)--对象创建(1)--抽象工厂

1. 意图 提供一个创建一系列相关或相互依赖对象的接口&#xff0c;而无需指定它们具体的类。 2. 四种角色 抽象产品(Product)、具体产品(Concrete Product)、抽象工厂(Abstract Factory)、具体工厂(Concrete Factory)。 3. 优点 3.1 分离了具体的类。Client只需使用抽象工厂类…

易生支付与青岛国资之间的合作即将成为现实。青岛国资决定以曲线入股易生支付。

易生金服的次要股权可能会有新的控制方。 根据西米支付网的消息&#xff0c;经营支付服务的持牌机构“易生支付”的唯一股东“易生金服”的第二大股东凯撒同盛发展股份有限公司的控股权将转让给青岛环海湾文化旅游发展有限公司&#xff0c;同时实际控制权也将交由青岛市市北区国…

java ATM swing窗体转账,取款,存款等

ATM 转账&#xff0c;取款&#xff0c;存款等等 开发环境 开发语言为Java&#xff0c;开发环境Eclipse或者IDEA都可以。 系统框架 利用JDK自带的 框架开发&#xff0c; 纯窗体模式&#xff0c;直接运行Main文件即可以。 涉及主要技术 银行ATM系统 系统用Java语言编写&a…

抖店做起来到底有多难?带你揭露抖音电商的真相!

我是电商珠珠 无论是谁问抖店还能做吗&#xff1f;基本上答案都是肯定的。他们只会说做店很简单&#xff0c;而不会告诉你做电商的压力&#xff0c;以及最真实的投资。 做抖店的风险他们都是一笔带过&#xff0c;好像无论是谁都能做一样。大部分电商公司都会让你做无货源&…

火力发电厂防雷及浪涌防护解决方案

火力发电厂是一种利用燃料燃烧产生的热能驱动汽轮机发电的设施&#xff0c;是目前世界上最常见的发电方式之一。火力发电厂的运行需要大量的电气设备&#xff0c;如辅机马达、通信系统、MIS系统、DCS系统等&#xff0c;这些设备对雷电分敏感&#xff0c;特别是DCS系统&#xff…

如何实现nacos的配置的热更新

我们在使用nacos进行修改配置后&#xff0c;需要微服务无需重启即可让配置生效&#xff0c;也就是使配置进行热更新我们可以采用下面的两种方式进行配置的热更新操作 方式一&#xff1a;在Value所注入的变量的类上添加注解RefreshScope RestController RequestMapping("/o…

Kubernetes(k8s)集群部署----->超详细

Kubernetes&#xff08;k8s&#xff09;集群部署-----&#xff1e;超详细 一、资源准备二、安装准备2.1 主机环境设置2.1.1 关闭操作系统防火墙、selinux2.1.2 关闭swap交换分区2.1.3 允许iptables检测桥接流量&#xff08;可选&#xff09; 2.2 安装Docker环境2.3 安装Kubeadm…

34、卷积实战 - 手写一个基础卷积算法

前面基本上把卷积这一算法的原理和公式介绍完了,如果还有不懂的,可以多翻几遍前面的章节内容,深入理解一下。 本节加一个实战,大家可以手动来实现一个卷积算法,本文中以 python 代码为例,C++ 的代码可以查看本节后面的链接。 说到卷积实现,其实就是自己手写一个卷积算…

pycharm中py文件设置参数

在py文件中右键 直接对应复制进去即可

python matplotlib set_aspect

说明: # 设置轴比例相等&#xff0c;以获得圆柱体视角 ax.set_aspect(equal) 代码案例: import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np# 创建数据 theta np.linspace(0, 2*np.pi, 100) z np.linspace(0, 1, 100) r z**2 …

Llama2-Chinese-7b-Chat安装部署

文章目录 前言一、文件介绍 &#x1f4c1;二、环境配置 ♟三、Llama2-Chinese-7b-Chat下载 ⏬总结 前言 本文主要介绍如何使用Llama2-Chinese-7b-Chat&#xff0c;最后的效果如图所示&#xff1a; 一、文件介绍 &#x1f4c1; ⬇️ 下载地址&#xff1a;https://pan.baidu.…

Facebook运营技巧详解,Facebook多店铺如何运营?

在前不久的文章中就讲过Facebook养号和广告的投放技巧&#xff0c;今天东哥就趁热打铁来接着讲讲Facebook的运营技巧&#xff0c;现在做外贸和跨境电商的人基本上都用过Facebook&#xff0c;像在流量这么庞大的平台上想要抓住更多机遇&#xff0c;懂得一些运营技巧是必不可少的…

室内空气污染愈演愈烈,新风系统如何实现呼吸自由

室内空气污染到底有多可怕&#xff1f;有研究发现&#xff0c;室内空气污染比室外空气污染严重2~3倍&#xff0c;甚至几十倍&#xff0c;我国每年有11.1万人因室内空气污染死亡&#xff0c;全球更是高达430万人&#xff0c;68%的人体疾病与室内污染有关&#xff0c;90%的白血病…

c++线程同步之条件变量

c线程同步之条件变量 ​ 条件变量是C11提供的另外一种用于等待的同步机制&#xff0c;它能阻塞一个或多个线程&#xff0c;直到收到另外一个线程发出的通知或者超时时&#xff0c;才会唤醒当前阻塞的线程。条件变量需要和互斥量配合起来使用&#xff0c;C11提供了两种条件变量…

Linux --绘制地图投影出现报错:无法成功下载地图背景数据

Linux --绘制地图投影出现报错&#xff1a;无法成功下载地图背景数据 主要原因是由于使用学院集群&#xff0c;该集群无法连接外网&#xff0c;在使用cartopy绘制地图投影时&#xff0c;导致无法成功加载地图背景数据解决方法也很简单&#xff0c;自己手动下载所需要的地形数据…

2023年【焊工(初级)】报名考试及焊工(初级)考试总结

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 焊工&#xff08;初级&#xff09;报名考试考前必练&#xff01;安全生产模拟考试一点通每个月更新焊工&#xff08;初级&#xff09;考试总结题目及答案&#xff01;多做几遍&#xff0c;其实通过焊工&#xff08;初…

案例041:基于微信小程序的私家车位共享系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

c++语法学习

C学习记录&#xff09; vs的安装代码的语法注释单行注释多行注释 main变量变量的定义整数类型浮点数字符型bool类型的定义sizeof(计算变量大小) 常量的定义defineconst 转义字符数据的输入cin 运算符算数运算符赋值运算符比较运算符逻辑运算符 程序流程结构顺序结构选择结构ifs…

Redis课程:黑马点评

文章目录 基于Redis实现短信登录商户查询缓存优惠券秒杀一人一单 分布式锁Redis分布式锁误删情况说明解决Redis分布式锁误删问题使用lua脚本解决分布式锁的原子性问题 基于阻塞队列实现秒杀优化Redis消息队列优化秒杀业务达人探店参考 本文是根据黑马程序员的视频课程 黑马程序…