forked from Gerkins/arithmeticSum
-
Notifications
You must be signed in to change notification settings - Fork 4
/
LRUCacheImpl.java
156 lines (136 loc) · 3.78 KB
/
LRUCacheImpl.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import java.util.HashMap;
/**
* Created by lrkin on 2016/11/1.
*/
public class LRUCacheImpl<K, V> implements LRUCache<K, V> {
static class Entry<K, V> {
public Entry prev;
public Entry next;
public K key;
public V value;
public Entry(Entry prev, Entry next, K key, V value) {
this.prev = prev;
this.next = next;
this.key = key;
this.value = value;
}
public Entry(V value) {
this.prev = null;
this.next = null;
this.key = null;
this.value = value;
}
}
public HashMap<K, V> entries;
public Entry<K, V> head;
public Entry<K, V> end;
public int MAX_SIZE;
public LRUCacheImpl(int MAX_SIZE) {
this.MAX_SIZE = MAX_SIZE;
this.head = new Entry<K, V>(null);
this.end = new Entry<K, V>(null);
}
/**
* 添加到缓存中
* <p>
* 需要先判断缓存是否已满
* 然后加到头部
*
* @param key
* @param value
*/
@Override
public void add(K key, V value) {
if (MAX_SIZE == entries.size()) {
entries.remove(end.key);
removeLastEntry();
}
entries.put(key, value);
Entry<K, V> entry = new Entry<>(null);
entry.key = key;
entry.value = value;
moveToHead(key);
}
private void removeLastEntry() {
end.prev.next = null;
end = end.prev;
}
private void removeHead() {
head.next.prev = null;
head = head.next;
}
@Override
public void remove(K key) {
entries.remove(key);
Entry<K, V> theNode = new Entry<K, V>(null);
Entry<K, V> headCopy = head;
//先找到,再删除
while (headCopy.next != null) {
if (headCopy.key == key)
theNode = headCopy;
else
headCopy = headCopy.next;
}
if (theNode.prev == null) {
removeHead();
} else if (theNode.next == null) {
removeLastEntry();
} else {
theNode.next.prev = theNode.prev;
theNode.prev.next = theNode.next;
}
}
public void moveToHead(K key) {
Entry<K, V> theNode = new Entry<K, V>(null);
Entry<K, V> headCopy = head;
while (headCopy.next != null) {
if (headCopy.key == key)
theNode = headCopy;
else
headCopy = headCopy.next;
}
//先找到,再移动
if (theNode.prev == null) {
return;
} else if (theNode.next == null) {
theNode.prev.next = null;
head.prev = theNode;
theNode.next = head;
theNode.prev = null;
} else {
theNode.next.prev = theNode.prev;
theNode.prev.next = theNode.next;
head.prev = theNode;
theNode.next = head;
theNode.prev = null;
}
if (end == null)
end = head;
}
/**
* 获取
* 每一次获取,都移至头部
*
* @param key
* @return
*/
@Override
public V get(K key) {
V value = entries.get(key);
moveToHead(key);
return value == null ? null : value;
}
public void print() {
System.out.print("");
}
public static void main(String[] args) {
LRUCacheImpl<String, Integer> stringIntegerLRUCache = new LRUCacheImpl<>(10);
String[] strings = {"A", "B", "C", "D", "E", "F", "G", "H", "U", "L", "Z"};
for (int i = 0; i < 10; i++) {
stringIntegerLRUCache.add(strings[i], i);
}
for (int i = 0; i < 10; i++) {
System.out.print(stringIntegerLRUCache.get(strings[i]) + " ");
}
}
}