Skip to content

Commit f756e30

Browse files
HARD/src/hard/LRUCache_use_DoublyLinkedList_plus_HashMap.java
1 parent d76dbfe commit f756e30

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package hard;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
public class LRUCache_use_DoublyLinkedList_plus_HashMap {
7+
private class Node {
8+
int key, value;
9+
Node prev, next;
10+
11+
Node(int k, int v) {
12+
this.key = k;
13+
this.value = v;
14+
}
15+
16+
Node() {
17+
this.key = 0;
18+
this.value = 0;
19+
}
20+
}
21+
22+
private int capacity;
23+
private int count;
24+
private Node head, tail;
25+
private Map<Integer, Node> map;// ATTN: the value should be Node type! This is the whole point
26+
// of having a class called Node!
27+
28+
public LRUCache_use_DoublyLinkedList_plus_HashMap(int capacity) {
29+
this.capacity = capacity;
30+
this.count = 0;// we need a count to keep track of the number of elements in the cache so
31+
// that we know when to evict the LRU one from the cache
32+
this.map = new HashMap();
33+
head = new Node();
34+
tail = new Node();
35+
head.next = tail;
36+
tail.prev = head;
37+
}
38+
39+
public int get(int key) {
40+
Node node = map.get(key);// HashMap allows value to be null, this is superior than
41+
// HashTable!
42+
if (node == null) {
43+
return -1;
44+
} else {
45+
update(node);
46+
return node.value;
47+
}
48+
}
49+
50+
public void set(int key, int value) {
51+
Node node = map.get(key);
52+
if (node == null) {
53+
node = new Node(key, value);
54+
map.put(key, node);
55+
add(node);
56+
count++;
57+
58+
if (count > capacity) {
59+
// ATTN: It's tail.prev, not tail, because tail is always an invalid node, it
60+
// doesn't contain anything, it's always the tail.prev that is the last node in the
61+
// cache
62+
Node toDelete = tail.prev;
63+
map.remove(toDelete.key);
64+
remove(toDelete);
65+
count--;
66+
}
67+
} else {
68+
remove(node);
69+
node.value = value;
70+
add(node);
71+
}
72+
}
73+
74+
private void update(Node node) {
75+
// this simplifies the process, just do two operations, remove the old node first, and then
76+
// just add the node again
77+
// this will guarantee that this node will be at the latest position: the most recently used
78+
// position.
79+
remove(node);
80+
add(node);
81+
}
82+
83+
private void remove(Node node) {
84+
Node next = node.next, prev = node.prev;
85+
prev.next = next;
86+
next.prev = prev;
87+
}
88+
89+
private void add(Node node) {// ATTN: we'll always add the node into the first position:
90+
// head.next!!!!
91+
Node next = head.next;
92+
head.next = node;
93+
node.next = next;
94+
node.prev = head;
95+
next.prev = node;
96+
}
97+
98+
}

0 commit comments

Comments
 (0)