解法一:使用双向链表(Linkedlist)+数组实现(数组arr[0]为key,arr[1]为value)。 需要了解的是,每次访问到的数据需要放到链表最前面,无论这个访问是get或是set,那么在set或者get进行之前,首先去缓存中查找是否已经有这个key。对于set操作:缓存中已经有key的情况下,需要把缓存原来的位置清空,然后把key-value放在链表头,没有key直接放在表头。对于get操作那就比较简单了,直接去链表中查询即可,命中也同样先清空数据并插入到表头。
public class Solution {
List<int[]>list = new LinkedList<int[]>();
int capacity = 0;
public Solution(int capacity) {
this.capacity = capacity;
}
public int get(int key) {
for(int i=0;i<capacity&&i<list.size();++i){
int [] temp = list.get(i);
if(temp[0]==key){
list.remove(i);
list.add(0,temp);
return temp[1];
}
}
return -1;
}
public void set(int key, int value) {
for(int i = 0;i<capacity&&i<list.size();++i){
if(list.get(i)[0]==key){
int[]temp = list.get(i);
list.remove(i);
temp[1] = value;
list.add(0,temp);
return ;
}
}
list.add(0,new int[]{key,value});
return ;
}
}
方法二:采用有序哈希(可以避免查找时的遍历情况)。LinkedHashSet会根据插入的先后进行一个排序,这种方法相比于使用链表的方式,只需要在超出容量时,把老数据remove即可(可以使用迭代器或者Entry获得超出那一部分数据)。
public class Solution {
Map<Integer,Integer> map = new LinkedHashMap<>();
int capacity = 0;
public Solution(int capacity) {
this.capacity = capacity;
}
public int get(int key) {
if(map.containsKey(key)){
int value = map.get(key);
map.remove(key);
map.put(key,value);
return value;
}
return -1;
}
public void set(int key, int value) {
if(map.containsKey(key))
map.remove(key);
map.put(key,value);
if(map.size()>capacity){
List<Map.Entry<Integer,Integer>> list = new ArrayList<>(map.entrySet());
for(int i=0;i<=map.size()-capacity;++i){
map.remove(list.get(i).getKey());
}
}
return ;
}
}