最近的項目中貌似需要一個這樣的隊列,想着實作了一下,後來又沒有使用,就沒有進行嚴格的測試.
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()
}
}