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 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 利用LRU(Least Recently Used)封装内存缓存LruCache,Kotlin版本。 -> 正文阅读

[移动开发]利用LRU(Least Recently Used)封装内存缓存LruCache,Kotlin版本。

LRU简介

LRU(Least Recently Used),即最近最少使用,是一种常用的页面置换算法,当需要存入的内容大于临界值的时候,选择最近最少使用的进行淘汰。

如果使用简单的数据结构描述的话,当前有一个栈,但是与栈不同的是,可以随时访问栈中的元素,并且访问过后将当前访问元素置于栈顶。

使用Kotlin写一个LruCache

实现原理

如果写一个缓存的话,一般都是keyvalue类型的,那么自然就会想到HashMap,但是HashMap是无序的。所以我们考虑使用LinkedHashMap,它内部在每一个Node节点上新增了before和after做成双向链表,用于记录指向顺序,可以表示插入顺序/访问顺序

我们这里就是用到其的访问顺序。这样每次我们从LinkedHashMap里面获取值的时候,该值就会跑到链表尾部,插入一个值也是在链表尾部。这样就完美实现类最近最少访问。接下来只需要在每次向map存值的时候,将大于我们所设置好的最大size的从栈头部便利去除即可。

代码

/**
 * LRU(Least Recently Used) 缓存算法,最近最少被使用,则被移除缓存
 *
 * @author pumpkin
 */
class LruCache<K, V>(maxSize: Int) {

    /**
     * 当前储存的size
     */
    private var currentSize = 0

    /**
     * 允许保存的最大的size,可以进行重置,不允许小于0
     */
    var maxSize = maxSize
        set(value) {
            if (value < 0) {
                throw IllegalStateException("maxSize 不允许小于0!")
            }
            synchronized(this) {
                field = value
                //重新计算,删除最旧的
                trimToSize()
            }
        }
        get() {
            synchronized(this) {
                return field
            }
        }

    /**
     * 缓存的容量为16,loadFactor为0.75F 与HashMap保持一致
     * 设置accessOrder为true,表示使用访问顺序,即一旦get某个值,该值就会被指向在链表的最后。默认为false,表示的是插入顺序。
     */
    private val cache = LinkedHashMap<K, V>(1 shl 4, 0.75F, true)

    var customSizeOf: ((key: K, value: V) -> Int)? = null

    /**
     * 删除最旧item,直到剩余的item的size小于maxSize
     */
    private fun trimToSize() {
        synchronized(this) {
            if (currentSize < 0 || (cache.isEmpty() && currentSize != 0)) {
                throw IllegalStateException("缓存size记录错误")
            }
            while (currentSize > maxSize) {
                val iterator = cache.entries.iterator()
                if (iterator.hasNext()) {
                    val (key, value) = iterator.next()
                    currentSize -= sizeOf(key, value)
                    iterator.remove()
                }
            }
        }
    }

    /**
     * null 检查
     */
    private fun <T> nullCheck(message: String, any: T?): T {
        if (any == null) {
            throw NullPointerException(message)
        }
        return any
    }

    /**
     * 获取值get
     */
    operator fun get(key: K?): V? {
        nullCheck("key 不允许等于 null", key)
        //利用linkedHashMap的特性,默认会将当前访问的链表指向到最后。
        return cache[key]
    }

    /**
     * 存值put
     * @return 若当前key之前存在值则返回,否则返回null
     */
    operator fun set(key: K?, value: V?): V? {
        nullCheck("key 不允许等于 null", key)
        nullCheck("value 不允许等于 null", value)

        val oldValue = synchronized(this) {
            val size = sizeOf(key!!, value!!)

            //如果存入size 大于maxSize 直接return
            if (size > maxSize) {
                return null
            }

            currentSize += size
            cache.put(key, value)?.also { oldValue ->
                currentSize -= sizeOf(key, oldValue)
            }
        }

        //位置移动
        trimToSize()

        return oldValue
    }

    /**
     * 默认每个item的size默认返回1,可以利用customSizeOf修改
     */
    private fun sizeOf(key: K, value: V): Int {
        val snapSizeOf = customSizeOf
        if (snapSizeOf != null) {
            return snapSizeOf(key, value)
        }
        return 1
    }

    /**
     * 清除所有的缓存
     */
    fun clearAll() {
        maxSize = 0
    }
}

代码GIT地址:????????????????????????里面有TestActivity包含具体使用方法。

创作不易,如有帮助一键三连咯🙆?♀?。欢迎技术探讨噢!

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-04-07 22:51:12  更:2022-04-07 22:52:55 
 
开发: 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/24 21:00:57-

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