随笔 - 126  文章 - 0  评论 - 300 

Java学习之LinkedHashMap学习总结

前言:

     在学习LRU算法的时候,看到LruCache源码实现是基于LinkedHashMap,今天学习一下LinkedHashMap的好处以及如何实现lru缓存机制的。

需求背景:

     LRU这个算法就是把最近一次使用时间离现在时间最远的数据删除掉,而实现LruCache将会频繁的执行插入、删除等操作,我们就会想到使用LinkedList,但是我们又要基于Key-Value来保存数据,这个时候我们就会想起HashMap,但是HashMap不能像linkedList那样保留数据的插入顺序,如果要使用HashMap的话可以使用它的一个子类LinkedHashMap。

LinkedHashMap介绍:

     LinkedHashMap是Map接口哈希表和链接列表实现,具有可预知的迭代顺序。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变, LinkedHashMap实现与HashMap的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序可以是插入顺序或者是访问顺序。根据链表中元素的顺序可以分为:按插入顺序的链表,和按访问顺序(调用get方法)的链表。默认是按插入顺序排序,如果指定按访问顺序排序,那么调用get方法后,会将这次访问的元素移至链表尾部,不断访问可以形成按访问顺序排序的链表。 可以重写removeEldestEntry方法返回true值指定插入元素时移除最老的元素。更多关于LinkedHashMap的知识介绍请查看这篇博客,博客地址:http://www.cnblogs.com/children/archive/2012/10/02/2710624.html

LinkedHashMap使用:

因为我们这里为了实现LRU算法,排序方式 设置为true 访问顺序排序

        int initialCapacity = 10;//初始化容量
        float loadFactor = 0.75f;//加载因子,一般是 0.75f
        boolean accessOrder = true;//排序方式 false 基于插入顺序  true  基于访问顺序
        Map<String, Integer> map = new LinkedHashMap<>(initialCapacity, loadFactor, accessOrder);

具体看下效果:

   for (int i = 0; i < 10; i++) {
            map.put(String.valueOf(i), i);
        }
        //访问前顺序
        for (Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry<String, Integer> next = it.next();
            Log.e(TAG, "linkedMap--before-->" + next.getKey());
        }

        //模拟访问
        map.get("5");

        //访问后数据
        for (Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry<String, Integer> next = it.next();
            Log.e(TAG, "linkedMap--after-->" + next.getKey());
        }
    }

运行结果发现访问过的5未知发生了变化 说明是基于访问排序的。我们接下来再看下如何移除过期的。

       final int initialCapacity = 10;//初始化容量
        float loadFactor = 0.75f;//加载因子,一般是 0.75f
        boolean accessOrder = true;//排序方式 false 基于插入顺序  true  基于访问顺序
        //Map<String, Integer> map = new LinkedHashMap<>(initialCapacity, loadFactor, accessOrder);
        Map<String, Integer> map = new LinkedHashMap(initialCapacity, loadFactor, accessOrder) {

            @Override
            protected boolean removeEldestEntry(Entry eldest) {
                return size() > initialCapacity;
            }
        };
        for (int i = 0; i < 15; i++) {
            map.put(String.valueOf(i), i);
        }
        //访问前顺序
        for (Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry<String, Integer> next = it.next();
            Log.e(TAG, "linkedMap--before-->" + next.getKey());
        }

我们容量定的10个,我们插入15个 我们发现最先插入的五个不见了,说明LRU算法起到效果了。

posted on 2016-07-31 08:45  总李写代码  阅读(5141)  评论(5编辑  收藏