• 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算法起到效果了。

  • 相关阅读:
    mongodb python image 图像存储读取
    python 编码 UnicodeDecodeError
    UnicodeDecodeError: 'gbk' codec can't decode byte 0xff in position 0: illegal multibyte sequence
    eclipse emacs
    mongodb windows install &python
    虚度的日子们
    C# list与数组互相转换
    C# 一个多层循环中,break一次能跳出几个循环?
    C# Byte[]、Image、Bitmap 之间的相互转换
    C# 写入和读出文本文件
  • 原文地址:https://www.cnblogs.com/whoislcj/p/5552421.html
Copyright © 2020-2023  润新知