缓存接口定义
/** * 缓存接口 * * @author zhi * */ public interface ICache<K, V> { /** * 添加缓存数据 * * @param key * @param value */ void put(K key, V value); /** * 获取缓存数据 * * @param key * @return */ V get(K key); /** * 删除缓存数据 * * @param key * @return */ V remove(K key); /** * 清除缓存 */ void clear(); }
利用LinkedHashMap实现
import java.util.LinkedHashMap; import java.util.Map; public class LRUCache<K, V> implements ICache<K, V> { private Map<K, V> map = null; @SuppressWarnings("serial") public LRUCache(final int maxCapacity) { map = new LinkedHashMap<K, V>(maxCapacity, 0.75f, true) { @Override protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) { return size() > maxCapacity; } }; } @Override public V get(K key) { return map.get(key); } @Override public synchronized void put(K key, V value) { map.put(key, value); } @Override public V remove(K key) { return map.remove(key); } @Override public void clear() { map.clear(); } }
利用双链表实现
import java.util.HashMap; public class LRUCache<K, V> implements ICache<K, V> { private final int maxCapacity; private CacheItem first; private CacheItem last; private HashMap<K, CacheItem> cache; public LRUCache(final int maxCapacity) { this.maxCapacity = maxCapacity; cache = new HashMap<K, CacheItem>(maxCapacity); } @Override public V get(K key) { CacheItem item = cache.get(key); if (item == null) { return null; } moveToFirst(item); return item.value; } @Override public synchronized void put(K key, V value) { CacheItem item = cache.get(key); if (item != null) { item.value = value; moveToFirst(item); } else { if (cache.size() == maxCapacity) { cache.remove(last.key); last = last.pre; if (last == null) { first = null; } else { last.next = null; } } item = new CacheItem(key, value); cache.put(key, item); if (first != null) { item.next = first; first.pre = item; } first = item; if (last == null) { last = item; } } } @Override public V remove(K key) { if (cache.containsKey(key)) { CacheItem item = cache.get(key); if (item.pre != null) { item.pre.next = item.next; } if (item.next != null) { item.next.pre = item.pre; } if (item == first) { first = item.next; } if (item == last) { last = item.pre; } return cache.remove(key).value; } else { return null; } } private void moveToFirst(CacheItem item) { if (item == first) { return; } if (item.next == null) { last = item.pre; } item.pre.next = item.next; item.next = first; first = item; first.pre = null; } @Override public void clear() { first = last = null; cache.clear(); } class CacheItem { CacheItem pre; CacheItem next; K key; V value; public CacheItem(K key, V value) { this.key = key; this.value = value; } } }