算法-LRU算法

LRU算法

LRU算法就是Least Recently Used,最近最少使用算法。 是一种内存管理算法,当内存占用到达一定阈值时,就移除掉最近最少使用的数据。LRU算法的实现,基于双向链表。 LRU算法设计原则是:长期不被使用的数据,在未来被使用的概率也不大。

看图说话

假设现在有一个链表,存有4个数据,最大容量也为4,如下图:

1、当程序需要获取数据2时,把数据2的前后引用都移除,插入到链表最右端;把数据1的后引用改为数据3,把数据3的前引用改为数据1。

2、此时,程序如果插入一条新数据5,那么链表数据情况如下:

3、又因为链表最大容量为4,所以应该移除最前端的数据1,最终的数据顺序如下图:

以上,就是LRU算法的基本思路,无外乎以上几种情况交替出现。

Kotlin代码的简单实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
class Data constructor(val key:String,var value:String) {
    var pre : Data? = null
    var next : Data? = null
}


class LRUCache constructor(val max: Int = 4) {
    private var head: Data? = null
    private var end: Data? = null

    private val map = HashMap<String, Data>()


    fun get(key: String): String? {
        val data = map[key] ?: return null
        moveToLast(data)
        return data.value
    }


    fun put(data: Data) {
        if (map.contains(data.key)) { //存在
            val old = map[data.key]
            old!!.value = data.value
            moveToLast(old)
        } else { //不存在
            if (map.size >= max) {
                remove(head!!)
                map.remove(head!!.key)
            }
            add(data)
            map[data.key] = data
        }
    }

    fun delete(key: String) {
        val data = map[key]
        if (null != data) {
            remove(data)
            map.remove(key)
        }
    }


    private fun moveToLast(data: Data) {
        if (end == data) {
            return
        }

        remove(data)
        add(data)
    }

    private fun remove(data: Data) {
        when (data) {
            end -> {
                end = end!!.pre
            }
            head -> {
                head = head!!.next
            }
            else -> { //中间情况,如文中所说的获取数据2的情况
                data.pre!!.next = data.next
                data.next!!.pre = data.pre
            }
        }
    }

    private fun add(data: Data) {
        if (null == head) head = data

        if (null != end) {
            end!!.next = data
            data.pre = end
            data.next = null
        }
        end = data

    }

    fun print(){
        var data:Data? =  head
        while(null != data){
            println(data.value)

            data = data.next
        }
    }
}

在Java中的实现是LinkedHashMap,线程不安全,继承自HashMap。
Android中缓存类LruCache,也是基于LinkedHashMap实现。

附件

lru.kt

延伸

Android缓存机制-LRU cache原理与用法
LruCache原理和用法与LinkedHashMap
LRU算法四种实现方式介绍

Built with Hugo
主题 StackJimmy 设计