`
beyondyuefei
  • 浏览: 12792 次
  • 性别: Icon_minigender_1
  • 来自: 福州
文章分类
社区版块
存档分类
最新评论

轻松扩展LinkedHashMap类实现LRU算法

 
阅读更多
    今天偶然看到某框架源码自带的简单缓存策略算法LRU的实现,不想就几行代码即实现,原来只是简单的扩展了 jdk自带的LinkedHashMap类,如此简单,故分享之。

     具体关于
LinkedHashMap 的描述 不懂的自己去看 jdk api 文档,这里只说说怎么实现,翻开LinkedHashMap 源码 我们可以看到一段描述:
/**
* Returns <tt>true</tt> if this map should remove its eldest entry.
* This method is invoked by <tt>put</tt> and <tt>putAll</tt> after
* inserting a new entry into the map. It provides the implementor
* with the opportunity to remove the eldest entry each time a new one
* is added. This is useful if the map represents a cache: it allows
* the map to reduce memory consumption by deleting stale entries.
*
* <p>Sample use: this override will allow the map to grow up to 100
* entries and then delete the eldest entry each time a new entry is
* added, maintaining a steady state of 100 entries.
* <pre>
* private static final int MAX_ENTRIES = 100;
*
* protected boolean removeEldestEntry(Map.Entry eldest) {
* return size() > MAX_ENTRIES;
* }
**/

protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
return false;
}
 

    意思就是说 在 put() 或者 putAll() 操作后会调用此方法判断 是否需要 清除最旧的那个元素,默认是返回 false,即不做操作。注意此 方法 是 protected ,即用于子类覆盖的,可以说这是 jdk的开发者特意留下来为我们实现LRU提供的,注释也说了,我们可以简单的覆盖此方法实现 LRU ,如:
public class LruCache implements Cache {

private final Map<Object, Object> store;
private int initialCapacity = 16;
private float loadFactor = 0.75f;
private boolean accessOrder = true;

public LruCache(URL url) {
final int max = 1000; // 缓存中最多1000个元素
this.store = new LinkedHashMap<Object, Object>(initialCapacity,loadFactor,accessOrder){
private static final long serialVersionUID = -3834209229668463829L;
@Override
protected boolean removeEldestEntry(Entry<Object, Object> eldest) {
return size() > max;
}
};
}
}
 

    这样当 stroe 中的元素超过 max=1000个时,将从 map 中删除 最旧的那个元素,即实现了 LRU。
需要注意的是,
LinkedHashMap 并未覆盖 父类 HashMap中的 put() 和 putAll() ,而是覆盖了 会被 put() 调用的addEntry() 方法,我们来看下LinkedHashMap中的addEntry() :

void addEntry(int hash, K key, V value, int bucketIndex) {
createEntry(hash, key, value, bucketIndex);

// Remove eldest entry if instructed, else grow capacity if appropriate
Entry<K,V> eldest = header.after;
if (removeEldestEntry(eldest)) {
removeEntryForKey(eldest.key);
}else {
if (size >= threshold)
resize(2 * table.length);
}
}
 

    看到了吧,如果返回为 true,则会删除最旧的那个元素,so simple
 
   ps: 如果在多线程环境下使用,由于其父类 HashMap不支持同步,所以需要重写 get put 方法,无非就是加个同步:
 
    
 public void put(Object key, Object value) {
        synchronized (store) {
            store.put(key, value);
        }
    }

    public Object get(Object key) {
        synchronized (store) {
            return store.get(key);
        }
    }
 
 
   
分享到:
评论

相关推荐

    LinkedHashMap的实现原理

    这是关于Java学习的主要针对LinkedHashMap的实现原理

    Java和Android的LRU缓存及实现原理

    Java提供了LinkedHashMap,可以用该类很方便的实现LRU算法,Java的LRULinkedHashMap就是直接继承了LinkedHashMap,进行了极少的改动后就可以实现LRU算法。 二、Java的LRU算法 Java的LRU算法的基础是LinkedHashMap,...

    Java和Android的Lru缓存及其实现原理

    Java提供了LinkedHashMap,可以用该类很方便的实现LRU算法,Java的LRULinkedHashMap是直接继承了LinkedHashMap,进行了极少的改动后可以实现LRU算法。  二、Java的LRU算法  Java的LRU算法的基础是LinkedHashMap...

    实现 LRU 算法,和 Caffeine 和 Redis 中的缓存淘汰策略.docx

    通过一个特殊的构造函数,三个参数的这种,最后一个布尔值参数表示是否要维护最近访问顺序,如果是 true 的话会维护最近访问的顺序,如果是 false 的话,只会维护插入...LinkedHashMap这种结构非常适合构造 LRU 缓存。

    leetcode下载-LruCache:实现LRU算法的Cache类

    SDK中的LruCache类参考实现的LRU算法缓存存储类. 原理 之前分析过Lru算法的实现方式:HashMap+双向链表,参考链接: 这里主要介绍Android SDK中LruCache缓存算法的实现. 构造函数 LruCache只有一个构造函数,并且有一个...

    深入Java集合学习系列(四):LinkedHashMap的实现原理

    深入Java集合学习系列(四): LinkedHashMap的实现原理

    leetcodelrucache-algorithm:算法学习和练习

    基于JavaLinkedHashMap实现的 LRU 算法 algorithm.consistentHashing ConsistentHash: 一致性Hash算法 algorithm.cap algorithm.subset 给一个set打印出所有子集 jdk jdk 知识 jdk.autoboxing 自动装箱拆箱 jdk....

    leetcode跳跃-datastructure:数据结构

    基于LinkedHashMap实现LRU算法 PalindromeBaseArray 基于数组实现回文串的判断 链表练习 SingleLinkedList 实现单链表的增、删、改、查操作 LRUBaseLinkedList 基于单链表实现LRU算法 PalindromeBaseLinked 基于链表...

    尚硅谷-深入Java集合4:LinkedHashMap的实现原理.pdf

    本教程特点: 1.更适合零基础学员: ·自Java语言起源始,循序渐进,知识点剖析细致且每章配备大量随堂练习,让你步步为营,学得透彻、练得明白 ·拒绝晦涩难懂的呆板教学,宋老师语言生动幽默,举例形象生动深入浅...

    尚硅谷-深入java8的集合4:LinkedHashMap的实现原理.pdf

    本教程特点: 1.更适合零基础学员: ·自Java语言起源始,循序渐进,知识点剖析细致且每章配备大量随堂练习,让你步步为营,学得透彻、练得明白 ·拒绝晦涩难懂的呆板教学,宋老师语言生动幽默,举例形象生动深入浅...

    ImageLoaderDemo图片三级缓存

    分成三级对图片进行缓存,第一级采用LinkedHashMap(LRU算法),第二季采用ConcurrentHashMap线程安全控制

    LinkedHashMap

    LinkedHashMap源代码,Java中Map的一种实现子类。

    android实现缓存图片等数据

    采用LinkedHashMap自带的LRU 算法缓存数据, 可检测对象是否已被虚拟机回收,并且重新计算当前缓存大小,清除缓存中无用的键值对象(即已经被虚拟机回收但未从缓存清除的数据);  * 默认内存缓存大小为: 4 * 1024 * ...

    今天会是有Offer的一天么:面试时不要再问我LinkedHashMap了

    要注意一点的是LinkedHashMap是可以实现LRU缓存策略的,前提是你需要将LinkedHashMap中的accessorder属性设置为true。 因此你基本可以认为LinkedHashMap是LinkedList和HashMap的一个组合。 LinkedHashMap简介 ...

    java软件技术文档-深入java8的集合4:LinkedHashMap的实现原理.pdf

    java软件技术文档

    LinkedHashmap的使用

    这个demo主要讲解了LinkedHashmap的使用,希望可以帮助需要的同学.

    集合常见面试题

    如何用LinkedHashMap实现LRU? 如何用TreeMap实现一致性hash? ConcurrentHashMap是如何在保证并发安全的同时提高性能? ConcurrentHashMap是如何让多线程同时参与扩容? LinkedBlockingQueue、DelayQueue是如何实现...

    JAVA工具类

    LruCacheUtils - 基于LinkedHashMap实现LRU缓存的工具类 MemcachedUtils - 基于memcached的工具类 RedisUtils - 基于redis的工具类,与redis的集群配置无缝结合 db JdbcUtils - 操作jdbc的工具类 MongodbUtils - ...

Global site tag (gtag.js) - Google Analytics