先のよりはまともだけれどやはり適当なキャッシュ

のはページの破棄理由がハッシュの衝突。しかもハッシュの計算方法が単なる剰余。といった具合に適当すぎたのでもう少しまともなのを作ってみた。

import java.util.Collections;
import java.util.Hashtable;
import java.util.Vector;
import java.util.List;
/**
 * LRU方式のキャッシュ
 * @author masahase
 *
 * @param <K>
 * @param <V>
 */
public class Cache<K, V> {
	private int size;
	private Hashtable<K,V> cache;
	private List<K> latest;
	/**
	 * コンストラクタ.
	 * 与えられたサイズ以上には大きくならないよう制御される
	 * @param max_size キャッシュサイズ
	 */
	public Cache(int max_size){
		size=max_size;
		cache=new Hashtable<K,V>(size);
		latest=Collections.synchronizedList(new Vector<K>());
	}
	/**
	 * 値の取得.
	 * 
	 * @param key
	 * @return
	 */
	public V get(K key){
		latest.remove(key);
		latest.add(key);
		return (V)cache.get(key);
	}
	/**
	 * 値の設定.
	 * キーと値のセットを登録すると共に、キャッシュサイズが設定されたサイズを超えそうならば一番最後にアクセスされたページを破棄する。
	 * @param key
	 * @param value
	 */
	public void put(K key,V value){
		if(cache.size()>size){
			cache.remove(latest.get(0));
			latest.remove(0);
		}
		latest.add(key);
		cache.put(key, value);
	}
	/**
	 * クリア
	 */
	public void clear(){
		latest.clear();
		cache.clear();
	}
}

JavaでGenericなクラスを書いたのは初めてかも。一応LRU*1でページの破棄を行っている。たぶんスレッドセーフ。

*1:Least Recently Used