天天看點

簡單的LRU隊列kotlin實作

最近的項目中貌似需要一個這樣的隊列,想着實作了一下,後來又沒有使用,就沒有進行嚴格的測試.

import java.util.*
import kotlin.concurrent.thread

/**
 * @describe 最近最少使用隊列, 隻能使用這裡override的api哦
 * @author  XQ Yang
 * @date 4/3/2019  3:09 PM
 */
class LRURequestTimeQueue<T>(val maxSize: Int, private val realQueue: LinkedList<T> = LinkedList()):Deque<T> by realQueue {

    val map = linkedMapOf<T,Long>()

    /**
     * 移除隊尾元素
     */
    override fun removeLast(): T {
        val last = realQueue.removeLast()
        if (last != null) {
            map.remove(last)
        }
        return last
    }

    /**
     * 如果存在則放到隊頭,更新通路時間,否則插入,如果隊滿,則删除隊尾元素
     */
    override fun addFirst(e: T) {
        if (contains(e)) {
            map[e] = System.currentTimeMillis()
            return
        }
        if (map.size + 1 > maxSize) {
            removeLast()
        }
        realQueue.addFirst(e)
        map[e] = System.currentTimeMillis()
    }


    /**
     * 如果包含則放到隊頭
     */
    override fun contains(element: T): Boolean {
        val contains = realQueue.contains(element)
        if (contains) {
            realQueue.remove(element)
            realQueue.addFirst(element)
        }
        return contains
    }

    /**
     * 擷取e對應的時間值,如果e不存在則會插入.如果存在則放到隊頭,更新通路時間
     */
    fun getAndUpdate(e: T): Long {
        if (contains(e)) {
            val old = map[e] ?: 0L
            map[e] = System.currentTimeMillis()
            return old
        } else {
            addFirst(e)
        }
        return 0L
    }

    /**
     * 檢視效果
     */
    fun print(){
        forEach {
            println("key=${it.toString()} value = ${map[it]}")
        }
    }

}


fun main() {
    val queue = LRURequestTimeQueue<String>(20)
    val list = mutableListOf<String>()
    for (i in 0..50) {
        list.add("test ${i}")
    }

    thread {
        for (i in 0..30) {
            Thread.sleep(kotlin.random.Random.nextLong(10))
            queue.getAndUpdate(list[kotlin.random.Random.nextInt(49)])
        }
        queue.print()
    }
}