IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> mybatis缓存LruCache源码分析 -> 正文阅读

[数据结构与算法]mybatis缓存LruCache源码分析

LruCache是如何实现的

LruCache的关键代码:

public class LruCache implements Cache {

  private final Cache delegate;
  private Map<Object, Object> keyMap;
  private Object eldestKey;

  public LruCache(Cache delegate) {
    this.delegate = delegate;
    // 设置缓存的键值对最大数量
    setSize(1024);
  }

  public void setSize(final int size) {
    /**
     * 重写方法:是否移除最老的链表节点,最老的链表节点就是链表的头节点
     */
    keyMap = new LinkedHashMap<Object, Object>(size, .75F, true) {
      private static final long serialVersionUID = 4267176411845948333L;

      @Override
      protected boolean removeEldestEntry(Map.Entry<Object, Object> eldest) {
        // 判断什么时候需要移除最老的节点
        boolean tooBig = size() > size;
        if (tooBig) {
          // 保存最老的链表节点的key,方便cycleKeyList()删除相应的key
          eldestKey = eldest.getKey();
        }
        return tooBig;
      }
    };
  }

  @Override
  public Object getObject(Object key) {
    // 虽然没有使用这个返回值,但是需要更细linkedHashMap的使用情况
    keyMap.get(key); // touch
    return delegate.getObject(key);
  }

  private void cycleKeyList(Object key) {
    /**
     * 这个方法会更新eldestKey的值
     * 此方法在hashMap当中,调用过程:hashmap.put()->linkedHashMap.afterNodeInsertion()->linkedHashMap.removeEldestEntry()
     * 最终eldestKey的值被更新
     */
    keyMap.put(key, key);
    // 如果eldestKey的值被更新,则需要到真正存储缓存的地方删除键值对
    if (eldestKey != null) {
      delegate.removeObject(eldestKey);
      eldestKey = null;
    }
  }

}

linkedHashMap源码分析

双向链表

链表优点

  1. 插入,删除,新增操作的时间复杂度都是O(1)
  2. 可以利用不连续的内存空间

链表缺点

  1. 不能随机查找,随机查找的时间复杂度是o(n)
  2. 因为要保存前后节点的引用,所以占用的内存空间会变大

双向链表节点

/**
     * 继承了HashMap.Node
     * 其实就是在hashMap节点的基础上加入before和after节点
     * 构成了双向链表的节点
     * @param <K>
     * @param <V>
     */
    static class Entry<K,V> extends HashMap.Node<K,V> {
        Entry<K,V> before, after;
        Entry(int hash, K key, V value, Node<K,V> next) {
            super(hash, key, value, next);
        }
    }

移动节点到链表的尾部

当get()被调用了,当前节点就变成最新被访问的了,需要移动到链表的尾部

void afterNodeAccess(Node<K,V> e) { // move node to last
        LinkedHashMap.Entry<K,V> last;
        /**
         * 两个判断逻辑:
         * 1 链表是否支持按照最近最新使用规则排序,默认按照插入顺序排序
         * 2 当前节点是否已经是尾节点了
         */
        if (accessOrder && (last = tail) != e) {
            LinkedHashMap.Entry<K,V> p =
                (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
            p.after = null;
            if (b == null) // 说明当前节点是head
                head = a; //重新定义head 
            else
                b.after = a; // 重新定义p.before的指向
            
            if (a != null) 
                a.before = b; // 重新定义p.after的指向
            else // a==null说明b已经是尾节点了
                last = b;
            
            if (last == null) // 说明当前链表为空
                head = p;
            else {   // 定义新的为节点
                p.before = last;
                last.after = p;
            }
            // 新的尾节点产生,可以看出移动链表的节点不需要通过遍历链表
            tail = p;
            ++modCount;
        }
    }

为什么要散列表和链表搭配使用

针对链表不能随机访问的缺点,如果使用散列表随机访问时间复杂度为O(1)的有点,两者扬长避短,充分发挥各自的优势

这样一来,可以创建有序的map键值对

public class LinkedHashMap<K,V>
    extends HashMap<K,V>
    implements Map<K,V>
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-12-05 12:17:23  更:2021-12-05 12:18:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 14:33:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码