最优解其实jdk中已经有解答,就是LinkedHashMap,但自己在限定时间写的话代码量大很难保证不出错,因此本例直接使用jdk中的HashMap+LinkedList实现。
由于实际使用的是LinkedList保存最近使用的key,遍历复杂度为O(n),因此速度并不快,只是更适合面试场合写
其中主要需要注意list删除时使用iterator,避免ConcurrentModificationException
class LRUCache {
int capacity = 0;
List<Integer> list = new LinkedList<>();
Map<Integer, Integer> valueMap = new HashMap<>();
public LRUCache(int capacity) {
this.capacity = capacity;
}
public int get(int key) {
Iterator<Integer> it = list.iterator();
if (valueMap.get(key) == null) return -1;
int v = valueMap.get(key);
//先去掉再加到队列头
while (it.hasNext()) {
if (key == (it.next())) {
it.remove();
}
}
list.add(0, key);
return v;
}
public void put(int key, int value) {
Iterator<Integer> it = list.iterator();
//容量未满不需要移除旧的
if (list.size() < capacity) {
//已存在则先去掉再加到队列头
if (valueMap.get(key) != null) {
while (it.hasNext()) {
if (key == (it.next())) {
it.remove();
}
}
}
valueMap.put(key, value);
list.add(0, key);
} else {
//put的key不存在原cache中
if (valueMap.get(key) == null) {
//去掉最久未使用的
int oldest = list.get(list.size() - 1);
valueMap.put(oldest, null);
while (it.hasNext()) {
if (oldest == it.next()) {
it.remove();
}
}
//添加新增的到队列头
list.add(0, key);
valueMap.put(key, value);
} else {
//put的key已经存在原cache中
while (it.hasNext()) {
if (key == it.next()) {
it.remove();
}
}
list.add(0, key);
valueMap.put(key, value);
}
}
}
}