JavaScript如何實現(xiàn)LRU緩存淘汰算法
如何實現(xiàn)LRU緩存淘汰算法?
LRU(Least Recently Used)緩存淘汰算法是一種常見的緩存淘汰策略,它的核心思想是優(yōu)先淘汰最近最少使用的緩存數(shù)據(jù),以保證緩存中的數(shù)據(jù)始終是最熱門的。下面是一些關(guān)于如何實現(xiàn)LRU緩存淘汰算法的方法:
使用哈希表和雙向鏈表
LRU緩存淘汰算法的核心在于如何快速定位最近最少使用的緩存數(shù)據(jù),這可以通過哈希表和雙向鏈表的結(jié)合來實現(xiàn)。具體來說,我們可以使用一個哈希表來存儲緩存數(shù)據(jù)的鍵值對,同時使用一個雙向鏈表來維護緩存數(shù)據(jù)的訪問順序,每次訪問緩存時,我們將訪問的數(shù)據(jù)節(jié)點移動到鏈表頭,當緩存滿時,淘汰鏈表尾部的節(jié)點即可。
哈希表實現(xiàn)LRU緩存淘汰算法
下面是一個使用哈希表實現(xiàn)LRU緩存淘汰算法的例子,假設(shè)我們要實現(xiàn)一個最大容量為3的緩存:
import java.util.HashMap; import java.util.Map; class LRUCache<K, V> { private int capacity; private Map<K, Node<K,V>> cache; private Node<K,V> head; private Node<K,V> tail; public LRUCache(int capacity) { this.capacity = capacity; this.cache = new HashMap<>(); this.head = new Node<>(null, null); this.tail = new Node<>(null, null); this.head.next = this.tail; this.tail.prev = this.head; } public V get(K key) { if (!cache.containsKey(key)) { return null; } Node<K,V> node = cache.get(key); remove(node); addFirst(node); return node.value; } public void put(K key, V value) { if (cache.containsKey(key)) { Node<K,V> node = cache.get(key); node.value = value; remove(node); addFirst(node); } else { if (cache.size() == capacity) { Node<K,V> node = removeLast(); cache.remove(node.key); } Node<K,V> node = new Node<>(key, value); cache.put(key, node); addFirst(node); } } private void remove(Node<K,V> node) { node.prev.next = node.next; node.next.prev = node.prev; } private void addFirst(Node<K,V> node) { node.next = head.next; node.prev = head; head.next.prev = node; head.next = node; } private Node<K,V> removeLast() { Node<K,V> node = tail.prev; remove(node); return node; } private static class Node<K, V> { K key; V value; Node<K,V> prev; Node<K,V> next; public Node(K key, V value) { this.key = key; this.value = value; } } }
在這個例子中,我們使用了一個哈希表cache
來存儲緩存數(shù)據(jù)的鍵值對,同時使用了一個雙向鏈表來維護緩存數(shù)據(jù)的訪問順序,其中head
和tail
分別表示鏈表頭和鏈表尾,每次訪問緩存時,我們將訪問的數(shù)據(jù)節(jié)點移動到鏈表頭,當緩存滿時,淘汰鏈表尾部的節(jié)點即可。
注意,為了方便起見,我們在鏈表頭和鏈表尾分別添加了一個哨兵節(jié)點head
和tail
,這樣就不需要在代碼中處理鏈表為空的情況了。
下面是一個使用雙向鏈表實現(xiàn)LRU緩存淘汰算法的例子,假設(shè)我們要實現(xiàn)一個最大容量為3的緩存:
import java.util.HashMap; import java.util.Map; class LRUCache<K, V> { private int capacity; private Map<K, Node<K,V>> cache; private Node<K,V> head; private Node<K,V> tail; public LRUCache(int capacity) { this.capacity = capacity; this.cache = new HashMap<>(); this.head = new Node<>(null, null); this.tail = new Node<>(null, null); this.head.next = this.tail; this.tail.prev = this.head; } public V get(K key) { if (!cache.containsKey(key)) { return null; } Node<K,V> node = cache.get(key); remove(node); addFirst(node); return node.value; } public void put(K key, V value) { if (cache.containsKey(key)) { Node<K,V> node = cache.get(key); node.value = value; remove(node); addFirst(node); } else { if (cache.size() == capacity) { Node<K,V> node = removeLast(); cache.remove(node.key); } Node<K,V> node = new Node<>(key, value); cache.put(key, node); addFirst(node); } } private void remove(Node<K,V> node) { node.prev.next = node.next; node.next.prev = node.prev; } private void addFirst(Node<K,V> node) { node.next = head.next; node.prev = head; head.next.prev = node; head.next = node; } private Node<K,V> removeLast() { Node<K,V> node = tail.prev; remove(node); return node; } private static class Node<K, V> { K key; V value; Node<K,V> prev; Node<K,V> next; public Node(K key, V value) { this.key = key; this.value = value; } } }
在這個例子中,我們使用了一個哈希表cache
來存儲緩存數(shù)據(jù)的鍵值對,同時使用了一個雙向鏈表來維護緩存數(shù)據(jù)的訪問順序,其中head
和tail
分別表示鏈表頭和鏈表尾,每次訪問緩存時,我們將訪問的數(shù)據(jù)節(jié)點移動到鏈表頭,當緩存滿時,淘汰鏈表尾部的節(jié)點即可。
注意,為了方便起見,我們在鏈表頭和鏈表尾分別添加了一個哨兵節(jié)點head
和tail
,這樣就不需要在代碼中處理鏈表為空的情況了。
到此這篇關(guān)于JavaScript如何實現(xiàn)LRU緩存淘汰算法的文章就介紹到這了,更多相關(guān)JavaScript LRU緩存淘汰算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
layer ui插件顯示tips時,修改字體顏色的實現(xiàn)方法
今天小編就為大家分享一篇layer ui插件顯示tips時,修改字體顏色的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09深入JavaScript高級程序設(shè)計之對象、數(shù)組(棧方法,隊列方法,重排序方法,迭代方法)
這篇文章主要介紹了深入JavaScript高級程序設(shè)計之對象、數(shù)組(棧方法,隊列方法,重排序方法,迭代方法)的相關(guān)資料,需要的朋友可以參考下2015-12-12Javascript基于對象三大特性(封裝性、繼承性、多態(tài)性)
這篇文章主要介紹了Javascript基于對象三大特性,包括封裝性、繼承性、多態(tài)性,感興趣的小伙伴們可以參考一下2016-01-01javascript實現(xiàn)保留兩位小數(shù)的多種方法
這篇文章主要介紹了javascript實現(xiàn)保留兩位小數(shù)的多種方法,如果數(shù)字的原本小數(shù)位數(shù)不到兩位,那么缺少的就自動補零,感興趣的小伙伴們可以參考一下2015-12-12js插件dropload上拉下滑加載數(shù)據(jù)實例解析
這篇文章主要為大家詳細解析了js插件dropload上拉下滑加載數(shù)據(jù)實例,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-07-07輕松實現(xiàn)HTML和JS之間的轉(zhuǎn)化的代碼
輕松實現(xiàn)HTML和JS之間的轉(zhuǎn)化的代碼...2007-09-09