本文使用數組實現最近最少使用緩存算法。
算法思想:
1、訪問某元素時,先判斷緩存中是否存在該元素。
2、如果存在,將該元素前面的元素向右移動一位,將該元素移動到數組首位。
3、如果不存在
1)數組已滿時,刪除末端元素,將所有元素向右移動一位,將新元素插到首位。
2)數組未滿時,將所有元素向后移動一位,將新元素插入到數組首位。
代碼實現
package com.datastructure.array;
import java.util.HashMap;
import java.util.Map;
/**
* 基於數組實現的LRU緩存
* 1. 空間復雜度為O(n)
* 2. 時間復雜度為O(n)
* 3. 不支持null的緩存
*
* @Auther: dlm
* @Date: 2020/4/6 17:31
*/
public class LRUBasedArray<T> {
//默認容量 2的3次方
private static final int DEFALUT_CAPACITY = (1 << 3);
//用戶自定義容量
private int capacity;
//現有元素個數
private int count;
//存儲元素的數組
private T[] value;
//存儲元素及其位置的對應關系
private Map<T,Integer> holder;
public LRUBasedArray(int capacity){
this.capacity = capacity;
this.count = 0;
this.value = (T[])new Object[capacity];
holder = new HashMap<>(capacity);
}
public LRUBasedArray(){
this(DEFALUT_CAPACITY);
}
//訪問某元素
public void offer(T value){
if(value == null){
throw new IllegalArgumentException("暫不支持null!");
}
Integer index = holder.get(value);
if(index == null){ //緩存中不存在該元素
if(isFull()){ //緩存已滿
removeAndCache(value);
}else{ //緩存未滿
cache(value,count);
}
}else { //緩存存在該元素
update(value,index);
}
}
private void removeAndCache(T e) {
T last = value[--count];
holder.remove(last);
cache(e,count);
}
private void update(T e, Integer index) {
rightShift(index);
value[0] = e;
holder.put(e,0);
}
private void cache(T e,int end) {
rightShift(end);
value[0] = e;
holder.put(e,0);
count++;
}
//將count之前的元素都向右移動
private void rightShift(int end) {
for(int i = end - 1;i >= 0 ;i--){
value[i+1] = value[i];
holder.put(value[i],i + 1);
}
}
private boolean isFull() {
return count == capacity;
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
for(int i = 0;i < count;i++){
stringBuilder.append(value[i]);
stringBuilder.append(" ");
}
return stringBuilder.toString();
}
static class TestLRUBasedArray{
public static void main(String[] args) {
testDefalutCapacity();
//testSpecificCapacity(4);
//testException();
}
public static void testDefalutCapacity(){
System.out.println("======無參測試========");
LRUBasedArray<Integer> lru = new LRUBasedArray<Integer>();
lru.offer(1);
lru.offer(2);
lru.offer(3);
lru.offer(4);
lru.offer(5);
System.out.println(lru);
lru.offer(6);
lru.offer(7);
lru.offer(8);
lru.offer(9);
System.out.println(lru);
}
public static void testSpecificCapacity(int capacity){
System.out.println("======有參測試========");
LRUBasedArray<Integer> lru = new LRUBasedArray<Integer>(capacity);
lru.offer(1);
System.out.println(lru);
lru.offer(2);
System.out.println(lru);
lru.offer(3);
System.out.println(lru);
lru.offer(4);
System.out.println(lru);
lru.offer(2);
System.out.println(lru);
lru.offer(4);
System.out.println(lru);
lru.offer(7);
System.out.println(lru);
lru.offer(1);
System.out.println(lru);
lru.offer(2);
System.out.println(lru);
}
public static void testException(){
LRUBasedArray<Integer> lru = new LRUBasedArray<Integer>();
lru.offer(null);
}
}
}
歡迎關注個人公眾號,可直接掃描以下二維碼或微信搜索“阿毛聊技術”。

