public class LRUBasedArray<T> {
private static final int DEFAULT_CAPACITY = (1 << 3);
private int capacity;
private int count;
private T[] value;
private Map<T, Integer> holder;
public LRUBasedArray() {
this(DEFAULT_CAPACITY);
}
public LRUBasedArray(int capacity) {
this.capacity = capacity;
value = (T[]) new Object[capacity];
count = 0;
holder = new HashMap<T, Integer>(capacity);
}
/**
* 模擬訪問某個值
* @param object
*/
public void offer(T object) {
if (object == null) {
throw new IllegalArgumentException("該緩存容器不支持null!");
}
Integer index = holder.get(object);
if (index == null) {
if (isFull()) {
removeAndCache(object);
} else {
cache(object, count);
}
} else {
update(index);
}
}
/**
* 若緩存中有指定的值,則更新位置
* @param end
*/
public void update(int end) {
T target = value[end];
rightShift(end);
value[0] = target;
holder.put(target, 0);
}
/**
* 緩存數據到頭部,但要先右移
* @param object
* @param end 數組右移的邊界
*/
public void cache(T object, int end) {
rightShift(end);
value[0] = object;
holder.put(object, 0);
count++;
}
/**
* 緩存滿的情況,踢出後,再緩存到數組頭部
* @param object
*/
public void removeAndCache(T object) {
T key = value[--count];
holder.remove(key);
cache(object, count);
}
/**
* end左邊的數據統一右移一位
* @param end
*/
private void rightShift(int end) {
for (int i = end - 1; i >= 0; i--) {
value[i + 1] = value[i];
holder.put(value[i], i + 1);
}
}
public boolean isContain(T object) {
return holder.containsKey(object);
}
public boolean isEmpty() {
return count == 0;
}
public boolean isFull() {
return count == capacity;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < count; i++) {
sb.append(value[i]);
sb.append(" ");
}
return sb.toString();
}
static class TestLRUBasedArray {
public static void main(String[] args) {
testDefaultConstructor();
testSpecifiedConstructor(4);
// testWithException();
}
private static void testWithException() {
LRUBasedArray<Integer> lru = new LRUBasedArray<Integer>();
lru.offer(null);
}
}
}