Skip to content

Commit fb0c353

Browse files
Merge pull request wangzheng0822#184 from SpecialYy/master
lruBasedArray
2 parents 0d2c3b0 + b3e8972 commit fb0c353

File tree

1 file changed

+173
-0
lines changed

1 file changed

+173
-0
lines changed
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
package linkedlist;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
/**
6+
* Created by SpecialYang in 2018/12/7 2:00 PM.
7+
*
8+
* 基于数组实现的LRU缓存
9+
* 1. 空间复杂度为O(n)
10+
* 2. 时间复杂度为O(n)
11+
* 3. 不支持null的缓存
12+
*/
13+
public class LRUBasedArray<T> {
14+
15+
private static final int DEFAULT_CAPACITY = (1 << 3);
16+
17+
private int capacity;
18+
19+
private int count;
20+
21+
private T[] value;
22+
23+
private Map<T, Integer> holder;
24+
25+
public LRUBasedArray() {
26+
this(DEFAULT_CAPACITY);
27+
}
28+
29+
public LRUBasedArray(int capacity) {
30+
this.capacity = capacity;
31+
value = (T[]) new Object[capacity];
32+
count = 0;
33+
holder = new HashMap<T, Integer>(capacity);
34+
}
35+
36+
/**
37+
* 模拟访问某个值
38+
* @param object
39+
*/
40+
public void offer(T object) {
41+
if (object == null) {
42+
throw new IllegalArgumentException("该缓存容器不支持null!");
43+
}
44+
Integer index = holder.get(object);
45+
if (index == null) {
46+
if (isFull()) {
47+
removeAndCache(object);
48+
} else {
49+
cache(object, count);
50+
}
51+
} else {
52+
update(index);
53+
}
54+
}
55+
56+
/**
57+
* 若缓存中有指定的值,则更新位置
58+
* @param end
59+
*/
60+
public void update(int end) {
61+
T target = value[end];
62+
rightShift(end);
63+
value[0] = target;
64+
holder.put(target, 0);
65+
}
66+
67+
/**
68+
* 缓存数据到头部,但要先右移
69+
* @param object
70+
* @param end 数组右移的边界
71+
*/
72+
public void cache(T object, int end) {
73+
rightShift(end);
74+
value[0] = object;
75+
holder.put(object, 0);
76+
count++;
77+
}
78+
79+
/**
80+
* 缓存满的情况,踢出后,再缓存到数组头部
81+
* @param object
82+
*/
83+
public void removeAndCache(T object) {
84+
value[--count] = null;
85+
cache(object, count);
86+
}
87+
88+
/**
89+
* end左边的数据统一右移一位
90+
* @param end
91+
*/
92+
private void rightShift(int end) {
93+
for (int i = end - 1; i >= 0; i--) {
94+
value[i + 1] = value[i];
95+
holder.put(value[i], i + 1);
96+
}
97+
}
98+
99+
public boolean isContain(T object) {
100+
return holder.containsKey(object);
101+
}
102+
103+
public boolean isEmpty() {
104+
return count == 0;
105+
}
106+
107+
public boolean isFull() {
108+
return count == capacity;
109+
}
110+
111+
@Override
112+
public String toString() {
113+
StringBuilder sb = new StringBuilder();
114+
for (int i = 0; i < count; i++) {
115+
sb.append(value[i]);
116+
sb.append(" ");
117+
}
118+
return sb.toString();
119+
}
120+
121+
static class TestLRUBasedArray {
122+
123+
public static void main(String[] args) {
124+
testDefaultConstructor();
125+
testSpecifiedConstructor(4);
126+
// testWithException();
127+
}
128+
129+
private static void testWithException() {
130+
LRUBasedArray<Integer> lru = new LRUBasedArray<Integer>();
131+
lru.offer(null);
132+
}
133+
134+
public static void testDefaultConstructor() {
135+
System.out.println("======无参测试========");
136+
LRUBasedArray<Integer> lru = new LRUBasedArray<Integer>();
137+
lru.offer(1);
138+
lru.offer(2);
139+
lru.offer(3);
140+
lru.offer(4);
141+
lru.offer(5);
142+
System.out.println(lru);
143+
lru.offer(6);
144+
lru.offer(7);
145+
lru.offer(8);
146+
lru.offer(9);
147+
System.out.println(lru);
148+
}
149+
150+
public static void testSpecifiedConstructor(int capacity) {
151+
System.out.println("======有参测试========");
152+
LRUBasedArray<Integer> lru = new LRUBasedArray<Integer>(capacity);
153+
lru.offer(1);
154+
System.out.println(lru);
155+
lru.offer(2);
156+
System.out.println(lru);
157+
lru.offer(3);
158+
System.out.println(lru);
159+
lru.offer(4);
160+
System.out.println(lru);
161+
lru.offer(2);
162+
System.out.println(lru);
163+
lru.offer(4);
164+
System.out.println(lru);
165+
lru.offer(7);
166+
System.out.println(lru);
167+
lru.offer(1);
168+
System.out.println(lru);
169+
lru.offer(2);
170+
System.out.println(lru);
171+
}
172+
}
173+
}

0 commit comments

Comments
 (0)