zoukankan      html  css  js  c++  java
  • Android之LinkedHashMap实现LRU

    先看下LinkedHashMap的数据结构图



    对于LinkedHashMap而言,它继承与HashMap、底层使用哈希表与双向链表来保存所有元素。其基本操作与父类HashMap相似,它通过重写父类相关的方法,来实现自己的链接列表特性。根据链表中元素的顺序可以分为:按插入顺序的链表,和按访问顺序(调用get方法)的链表。

    LinkedHashMap采用的hash算法和HashMap相同,但是它重新定义了数组中保存的元素Entry,该Entry除了保存当前对象的引用外,还保存了其上一个元素before和下一个元素after的引用,从而在哈希表的基础上又构成了双向链接列表。

    LinkedHashMap定义了排序模式accessOrder,该属性为boolean型变量,对于访问顺序,为true;对于插入顺序,则为false。

    当有新元素加入Map的时候会调用Entry的addEntry方法,会调用removeEldestEntry方法,这里就是实现LRU元素过期机制的地方,默认的情况下removeEldestEntry方法只返回false表示元素永远不过期

    public class Tester {
        private static int MAX=5;
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            HashMap<String,String> map = new LinkedHashMap<String, String>(MAX/2,0.5f,true)
            {
                @Override
                protected boolean removeEldestEntry(Map.Entry<String, String> eldest){
                    if(size()>MAX){
                        return true;
                    }
                    return false;
                }
            };
            map.put("a", "a");
            map.put("b", "b");
            map.put("c", "c");
            map.put("d", "d");
            map.put("e", "e");
            map.put("c", "c");
            for (Map.Entry<String, String> entry : map.entrySet()) {  
                System.out.print(entry.getValue() + ", ");  
            }  
            System.out.println();
            
            map.get("b");
            for (Map.Entry<String, String> entry : map.entrySet()) {  
                System.out.print(entry.getValue() + ", ");  
            }  
            System.out.println();
            
            map.put("f", "f");
            for (Map.Entry<String, String> entry : map.entrySet()) {  
                System.out.print(entry.getValue() + ", ");  
            }  
            System.out.println();
        }
    
    }

    a, b, d, e, c,
    a, d, e, c, b,
    d, e, c, b, f,

     

    可见最新加入的或者最近get过的就会往最后放,如果put数目大于max,就会把头上那个去掉,然后f加到最后,其他往前移。

    所以说不只是put,get也会把Entry往后方,越往后的说明最近才访问过的,越往前的说明最近最少访问的,这就实现了一个简单的LRU。

    参考:

    http://uule.iteye.com/blog/1522291

    http://woming66.iteye.com/blog/1284326

  • 相关阅读:
    如何唤醒一个处于阻塞状态下的线程
    如何终止一个线程
    网络编程基础_5.1聊天室-客户端
    网络编程基础_4.2TCP-客户端
    网络编程基础_4.1TCP_服务端
    网络编程基础_3.APC队列
    网络编程基础_2.等待事件
    网络编程基础_1.等待句柄
    Window提高_3.1练习_双进程守护
    Windows提高_2.3第三部分:内核区同步
  • 原文地址:https://www.cnblogs.com/cqcmdwym/p/3370043.html
Copyright © 2011-2022 走看看