在java中,通常可以使用HashMap作为cache来加速程序的运行。一般地,若对一个方法的结果进行缓冲,仅需要将方法的参数列表作为key,方法的返回结果作为value即可。
但若程序对该方法访问过于频繁,大量的缓冲信息占用大量内存,严重的情况下会导致内存不足而异常退出。如果可以在HashMap达到一定大小后,自动删除最早放入HashMap那部分数据,就可以达到缓冲大小的控制。然而,HashMap是一个无序的数据结构,我们并不能从HashMap中获取到每条记录入库的先后顺序。
解决方法:可以使用List嵌套HashMap的方法来实现一个简单的FIFO缓冲淘汰方法。list中可以放4个HashMap,有限填写list中的第一个HashMap,当HashMap填写了1000条时,则将list最后一个HashMap从list删除,在list第一个位置插入一个新的HashMap。
通过如上方法构造的缓冲区最多存储4000条信息,当达到4000条信息后,会自动清理最先进入缓冲区的1000条信息。
使用该方法的代价是判断一条数据在不在缓冲区中时需要访问4个HashMap并调用containsKey。此代价相对于缓冲的方法来说可忽略不计。
下面是一些代码的片段
class BufferMap<K,V>{
private static final int QUEUE_LEN=4;
ArrayList<HashMap<K,V>> queue = new ArrayList<>();
private final int buffersize;
public BufferMap(int buffersize){
this.buffersize=buffersize;
for(int i=0;i<QUEUE_LEN;i++){
queue.add(new HashMap<K,V>());
}
}
public void put(K key,V value){
if(queue.get(queue.size()-1).size()>=buffersize/QUEUE_LEN && !queue.get(queue.size()-1).containsKey(key)){
HashMap<K, V> remove = queue.remove(0);
remove.clear();
queue.add(remove);
}
queue.get(queue.size()-1).put(key, value);
}
public V get(K key){
for(HashMap<K,V> hm:queue){
if(hm.containsKey(key)){
return hm.get(key);
}
}
return null;
}
}