mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-07 09:45:04 +08:00
refactor: LFUCache
(#5369)
This commit is contained in:
@ -10,8 +10,7 @@ import java.util.Map;
|
|||||||
public class LFUCache<K, V> {
|
public class LFUCache<K, V> {
|
||||||
|
|
||||||
private class Node {
|
private class Node {
|
||||||
|
private final K key;
|
||||||
private K key;
|
|
||||||
private V value;
|
private V value;
|
||||||
private int frequency;
|
private int frequency;
|
||||||
private Node previous;
|
private Node previous;
|
||||||
@ -26,67 +25,67 @@ public class LFUCache<K, V> {
|
|||||||
|
|
||||||
private Node head;
|
private Node head;
|
||||||
private Node tail;
|
private Node tail;
|
||||||
private Map<K, Node> map = null;
|
private final Map<K, Node> cache;
|
||||||
private Integer capacity;
|
private final int capacity;
|
||||||
private static final int DEFAULT_CAPACITY = 100;
|
private static final int DEFAULT_CAPACITY = 100;
|
||||||
|
|
||||||
public LFUCache() {
|
public LFUCache() {
|
||||||
this.capacity = DEFAULT_CAPACITY;
|
this(DEFAULT_CAPACITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LFUCache(Integer capacity) {
|
public LFUCache(int capacity) {
|
||||||
|
if (capacity <= 0) {
|
||||||
|
throw new IllegalArgumentException("Capacity must be greater than zero.");
|
||||||
|
}
|
||||||
this.capacity = capacity;
|
this.capacity = capacity;
|
||||||
this.map = new HashMap<>();
|
this.cache = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns value present in the cache corresponding to the key passed as parameter
|
* Retrieves the value for the given key from the cache. Increases the frequency of the node.
|
||||||
*
|
*
|
||||||
* @param <K> key for which value is to be retrieved
|
* @param key The key to look up.
|
||||||
* @returns <V> object corresponding to the key passed as parameter, returns null if <K> key is
|
* @return The value associated with the key, or null if the key is not present.
|
||||||
* not present in the cache
|
|
||||||
*/
|
*/
|
||||||
public V get(K key) {
|
public V get(K key) {
|
||||||
if (this.map.get(key) == null) {
|
Node node = cache.get(key);
|
||||||
|
if (node == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node node = map.get(key);
|
|
||||||
removeNode(node);
|
removeNode(node);
|
||||||
node.frequency += 1;
|
node.frequency += 1;
|
||||||
addNodeWithUpdatedFrequency(node);
|
addNodeWithUpdatedFrequency(node);
|
||||||
|
|
||||||
return node.value;
|
return node.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method stores <K> key and <V> value in the cache
|
* Adds or updates a key-value pair in the cache. If the cache is full, the least frequently used item is evicted.
|
||||||
*
|
*
|
||||||
* @param <K> key which is to be stored in the cache
|
* @param key The key to insert or update.
|
||||||
* @param <V> value which is to be stored in the cache
|
* @param value The value to insert or update.
|
||||||
*/
|
*/
|
||||||
public void put(K key, V value) {
|
public void put(K key, V value) {
|
||||||
if (map.containsKey(key)) {
|
if (cache.containsKey(key)) {
|
||||||
Node node = map.get(key);
|
Node node = cache.get(key);
|
||||||
node.value = value;
|
node.value = value;
|
||||||
node.frequency += 1;
|
node.frequency += 1;
|
||||||
removeNode(node);
|
removeNode(node);
|
||||||
addNodeWithUpdatedFrequency(node);
|
addNodeWithUpdatedFrequency(node);
|
||||||
} else {
|
} else {
|
||||||
if (map.size() >= capacity) {
|
if (cache.size() >= capacity) {
|
||||||
map.remove(this.head.key);
|
cache.remove(this.head.key);
|
||||||
removeNode(head);
|
removeNode(head);
|
||||||
}
|
}
|
||||||
Node node = new Node(key, value, 1);
|
Node node = new Node(key, value, 1);
|
||||||
addNodeWithUpdatedFrequency(node);
|
addNodeWithUpdatedFrequency(node);
|
||||||
map.put(key, node);
|
cache.put(key, node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method stores the node in the cache with updated frequency
|
* Adds a node to the linked list in the correct position based on its frequency.
|
||||||
*
|
*
|
||||||
* @param Node node which is to be updated in the cache
|
* @param node The node to add.
|
||||||
*/
|
*/
|
||||||
private void addNodeWithUpdatedFrequency(Node node) {
|
private void addNodeWithUpdatedFrequency(Node node) {
|
||||||
if (tail != null && head != null) {
|
if (tail != null && head != null) {
|
||||||
@ -123,9 +122,9 @@ public class LFUCache<K, V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method removes node from the cache
|
* Removes a node from the linked list.
|
||||||
*
|
*
|
||||||
* @param Node node which is to be removed in the cache
|
* @param node The node to remove.
|
||||||
*/
|
*/
|
||||||
private void removeNode(Node node) {
|
private void removeNode(Node node) {
|
||||||
if (node.previous != null) {
|
if (node.previous != null) {
|
||||||
|
Reference in New Issue
Block a user