java系列-LinkedHashMap怎么实现LRU

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Maven】加载 Maven 项目报错 status code: 501, reason phrase: HTTPS Required (501)

问题描述 加载 Maven 项目报错&#xff0c;错误信息如下&#xff1a; status code: 501, reason phrase: HTTPS Required (501)尝试使用 -U 标记(强制更新快照)运行 Maven 导入原因分析 这个错误通常表示 Maven 在尝试从远程仓库下载依赖时遇到了 HTTPS 必需的错误。 解决方…

AI数字人克隆采集规范分享!

数字人直播的时代已经来临&#xff0c;使用青否数字人SaaS系统数字人源码&#xff1a;zhibo175&#xff09;去生成数字人&#xff0c;那如何能得到自己想要的效果呢&#xff1f;需要注意一下几点&#xff1a; 一.摄影棚灯光方案 中型(15m左右)摄影棚​ 适用于美妆/珠宝等直播&a…

照片如何抠图换背景?分享三个一键抠图的方法

照片如何抠图换背景&#xff1f;通过使用一键抠图工具&#xff0c;您可以将图片中的主体从原始背景中分离出来&#xff0c;并将其放置在新的背景中。这种技术可以用于各种情况&#xff0c;例如在照片编辑中增加创意效果、改变照片的氛围或者为产品展示添加专业外观。通过抠图并…

如何本地搭建WampServer并结合cpolar内网穿透实现远程访问

文章目录 前言1.WampServer下载安装2.WampServer启动3.安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4.固定公网地址访问 前言 Wamp 是一个 Windows系统下的 Apache PHP Mysql 集成安装环境&#xff0c;是一组常用来…

自助式可视化开发,ETLCloud的集成之路

自助式可视化开发 自助式可视化开发是指利用可视化工具和平台&#xff0c;使非技术人员能够自主创建、定制和部署数据分析和应用程序的过程。 传统上&#xff0c;数据分析和应用程序开发需要专业的编程和开发技能。但是&#xff0c;自助式可视化开发工具的出现&#xff0c;使…

喜讯 | 同立海源生物入选2023年国创中心细胞疗法“揭榜挂帅”技术攻关项目

近日&#xff0c;2023年国家生物药技术创新中心细胞疗法“揭榜挂帅”技术攻关拟立项目名单公示&#xff0c;北京同立海源生物科技有限公司&#xff08;简称“同立海源生物”&#xff09;参评的 “细胞分选激活磁珠研发项目” 凭借公司多年在细胞分选磁珠领域的技术沉淀和创新性…

对比SPI、UART、I2C通信的区别与应用

SPI、UART、I2C通信是常用的数字通信协议&#xff0c;它们在不同的场景下有不同的应用。下面&#xff0c;我将分别介绍它们的特点、区别与应用。 SPI通信 SPI通信是一种串行同步通信协议&#xff0c;它的全称为“Serial Peripheral Interface”。SPI通信是一种单主多从的通信方…

k8s如何部署seata(分布式事务)?(第一篇)

k8s如何部署seata(分布式事务)&#xff1f; 官方传送门https://seata.io/zh-cn/ 快速入门SEATA Seata 是一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式&#xff0c;为用户打造一站…

智谱AI副总裁郑叔亮:交付情感价值是大模型的重要发展趋势

“ 提供情绪价值是大模型下一步要走的路&#xff0c;这条路会逐渐开阔 ” 整理 | 梦婕 编辑 | 云舒 出品&#xff5c;极新 2023年11月28日上午&#xff0c;在极新AIGC行业峰会现场&#xff0c;智谱AI总裁郑叔亮围绕国内外大模型发展现状与未来方向做了一场主题为《大…

Mistral AI 推出高质量的稀疏专家混合AI人工智能模型——SMoE,有望超越ChatGPT3.5

Mistral AI&#xff08;“Mistral AI”是一家由前DeepMind和Meta Platforms&#xff08;META.US&#xff09;的研究人员组建的新公司。&#xff09;继续履行为开发者社区提供最佳开放模型的使命。他们发布了 Mixtral 8x7B&#xff0c;这是一个高质量的稀疏专家混合模型&#xf…

【数据结构与算法】JavaScript实现图结构

文章目录 一、图论1.1.图的简介1.2.图的表示邻接矩阵邻接表 二、封装图结构2.1.添加字典类和队列类2.2.创建图类2.3.添加顶点与边2.4.转换为字符串输出2.5.图的遍历广度优先搜索深度优先搜索 2.6.完整实现 一、图论 1.1.图的简介 什么是图&#xff1f; 图结构是一种与树结构…

stateflow 之图函数、simulink函数和matlab函数使用及案例分析

目录 前言 1. 图函数graph function 2.simulink function 3.matlab function 4.调用stateflow中的几种函数方式 前言 对于stateflow实际上可以做simulink和matlab的所有任务&#xff0c;可以有matlab的m语言&#xff0c;也可以有simulink的模块&#xff0c;关于几种函数在…

Ansible中执行流控制

1.ansible中的迭代循环 创建目录和文件 vim createfile.yaml - name: create file playbook hosts: all tasks: - name: create file file: path: "/mnt/{{item[name]}}" state: …

小新Air-14 Plus 2021款AMD ACN版(82L7)原装出厂Win11系统镜像

LENOVO联想笔记本开箱状态原厂Windows11系统包 链接&#xff1a;https://pan.baidu.com/s/1D_sYCJAtOeUu9RbTIXgI3A?pwd96af 提取码&#xff1a;96af 联想小新AIR14笔记本电脑原厂系统自带所有驱动、出厂主题壁纸、Office办公软件、联想电脑管家等预装程序 所需要工具&am…

【C语言】RDMACM、Verbs API与epoll一起使用的示例

一、epoll介绍 epoll是Linux内核为处理大批量文件描述符而作了改进的poll&#xff0c;是Linux下多路复用IO接口select/poll的增强版本&#xff0c;它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。 以下是epoll的主要使用方法和优点&#xff1a; epo…

【python】多任务编程

python多任务编程 有哪些编程提速的方法 单线程串行&#xff1a;不加改造的程序 多线程并发&#xff1a;利用CPU和IO可以同时执行的原理&#xff0c;让CPU不会干巴巴等待IO完成 多CPU并行/多进程&#xff1a;利用多核CPU的能力&#xff0c;真正的并行执行任务 多机器并行&#…

快速学习Java Agent

1.1 java agent原理 我们知道&#xff0c;要使用Skywalking去监控服务&#xff0c;需要在其 VM 参数中添加 “- javaagent:/usr/local/skywalking/apache-skywalking-apm-bin/agent/skywalking-agent.jar"。这里就 使用到了java agent技术。 Java agent 是什么&#xff…

python tkiinter中滑块的使用

需求&#xff1a;需要在Canvas组件上添加滑块功能 解决&#xff1a;使用tkinter提供的Scrollbar组件&#xff0c;由于没发现直接在画布上显示滑块功能的方法&#xff0c;所以后面采用在显示画布的容器上显示滑块&#xff0c;并绑定到画布上。 具体案例demo&#xff1a; from t…

视频滤波驱动器电路D1671 D1675的性能描述和分析

D1671四阶标清视频滤波器驱动&#xff0c;1CH&#xff0c;工作电压2.8V~5.5V&#xff0c;转换速率40V/s D1675六阶高清视频滤波器驱动&#xff0c;1CH&#xff0c;工作电压2.5V~5.5V&#xff0c;转换速率400V/s

02鸿蒙APP真机运行及证书签名打包

目录 1、真机运行1.1、运行安装错误1.2、解决方案&#xff1a;第一步&#xff1a;安装兼容真机的sdk版本2.2.0&#xff08;API6&#xff09;&#xff0c;如下图所示&#xff1a;第二步&#xff1a;新建一个API6的工程项目第三步&#xff1a;运行API6创建的工程项目第四步&#…