使用LinkedHashMap实现Cache的方法与原理
基于LinkedHashMap的特性,可以实现一个简单的基于LRU算法的缓存功能。
首先大致介绍一下LinkedHashMap的特点。
通过LinkedHashMap的签名我们可以看出 LinkedHashMap是HashMap的一个子类,它根据自身的特点修改了某些某类的方法
在这里八卦一下这个签名,我们可以看到LinkedHashMap继承了HashMap并实现了Map接口。
我们再来看一下HashMap的签名,HashMap继承了AbstractMap 并实现了Map接口,
我们再来看一下AbstractMap的签名
AbstractMap本身也实现了Map接口
但为什么HashMap和LinkedHashMap还要实现这个接口呢
在stackoverflow.网站找到了一个类似的帖子,只不过帖子问的是有关于WeakHashMap这个类的,但其道理是一样的
回复如下
大概意思是说只是为了生成javadoc会比较良好,其实在语法上是不需要的。
设计原理
LinkedHashMap我们都知道是基于双向链表的,如下图
但LinkedHashMap代源码中我们可以看出,他不仅是一个双向链表,而且是一个环型的双向链表
我们在源码可以看到LinkedHashMap的init方法覆盖了父类的方法
然而在HashMap类中init方法仅仅是一个空实现,为子类提供了一个勾子的作用
访问顺序
LinkedHashMap提供了两种Key的顺序
<!--[if !supportLists]-->l <!--[endif]-->访问顺序
<!--[if !supportLists]-->l <!--[endif]-->插入顺序
LinkedHashMap默认是插入顺序,这点我们在它的构造函数中可以看到
accessOrder就是访问顺序的意思,默认为false,即使用插入顺序
使用访问顺序的好处是,当我们使用get方法访问元素的时候,在访问过后,LinkedHashMap会将get的元素移到链表的尾部,这样链表的第一个元素总是最早被放入到链表中并且没有被访问过的元素,正好符合我们的LRU原则。
通过源码我们可以看到
LinkedHashMap并没有重写父类的put方法,
但是LinkedHashMap重新了父类put方法中的子方法addEntry方法
在addEntry方法中,我们看到了有一段代码,是否删除最老的一个元素。
按此推理,我们在实现缓存功能的时候,就需要重写removeEldestEntry方法,在添加元素的时候判断是否超过了缓存定义的容量。
按此方法,我在本地实现了一个简单的cache功能,代码如下
就这么简单。
测试代码如下:
1. 元素大小小于缓存容量
运行结果
2. 元素大小大于缓存容量
运行结果
3. 元素大小大于缓存容量,在缓存容量满之前对缓存数据进行访问
运行结果
相关推荐
这是关于Java学习的主要针对LinkedHashMap的实现原理
深入Java集合学习系列(四): LinkedHashMap的实现原理
这个demo主要讲解了LinkedHashmap的使用,希望可以帮助需要的同学.
·课程中,Eclipse和IDEA这两种企业一线开发环境都使用到了 3.技术讲解更深入、更全面: ·课程共30天,715个知识视频小节,涉及主流Java使用的方方面面,全而不冗余 ·全程内容涵盖数据结构、设计模式、JVM内存...
在理解了#7 介绍的HashMap后,我们来学习LinkedHashMap的工作原理及实现。首先还是类似的,我们写一个简单的LinkedHashMap的程序: LinkedHashMap<String> lmap = new LinkedHashMap(); lmap.put(语文, 1)...
LinkedHashMap源代码,Java中Map的一种实现子类。
·课程中,Eclipse和IDEA这两种企业一线开发环境都使用到了 3.技术讲解更深入、更全面: ·课程共30天,715个知识视频小节,涉及主流Java使用的方方面面,全而不冗余 ·全程内容涵盖数据结构、设计模式、JVM内存...
Set是使用LinkedHashMap在Go(Golang)中简单的Set数据结构实现。 该库允许您获取一组int64或string而没有重复的项目。 用法 package main import ( "fmt" "github.com/StudioSol/set" ) func main () { ...
HashMap,HashTable,LinkedHashMap,TreeMap的区别
java软件技术文档
主要介绍了Java使用LinkedHashMap进行分数排序的相关代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
LinkedHashMap是Java中的一种特殊类型的HashMap,它保留了插入顺序,即按照元素插入的先后顺序进行排序
java中HashMap,LinkedHashMap,TreeMap,HashTable的区别
介绍LinkedHashMap的底层原理 请介绍TreeMap的底层原理 Map和Set有什么区别 ArrayList和LinkedList有什么区别 有哪些线程安全的List 介绍一下ArrayList的数据结构 谈谈CopyOnWriteArrayList的原理 说一说TreeSet和...
(当然也可以用hashbrown )用法将ritelinked添加到Cargo.toml :ritelinked =" x.y.z"写一些这样的代码:letmut lru_cache= LinkedHashMap::new ();let key="key" .to_owned ();let _cached_val= lru_cache .raw_...
主要介绍了 java HashMap,TreeMap与LinkedHashMap的详解的相关资料,这里提供实例代码,帮助大家学习理解 这部分的内容,需要的朋友可以参考下
要注意一点的是LinkedHashMap是可以实现LRU缓存策略的,前提是你需要将LinkedHashMap中的accessorder属性设置为true。 因此你基本可以认为LinkedHashMap是LinkedList和HashMap的一个组合。 LinkedHashMap简介 ...
LRUCache内部使用LinkedHashMap来存储key-value键值对,并将LinkedHashMap设置为访问顺序来体现LRU算法。 无论是对某个key的get,还是set都算做是对该key的一次使用。当set一个不存在的key,并且LRU Cache中key的...
// 常用的map接口的实现类有HashMap,LinkedHashMap和TreeMap // HashMap不保证集合中元素的顺序, // LinkedHashMap按插入顺序排序 // TreeMap按自己的意愿进行排序,默认按key值升序排序。 另包含一篇网文:在java...