如何在达到限制时删除最旧的条目来限制地图的最大大小 [已关闭]
2022-09-01 05:40:30
我想要一个具有最大大小的Map实现。我想将其用作缓存,因此一旦达到限制,就会删除最旧的条目。
我也不想引入对任何第三方库的依赖。
我想要一个具有最大大小的Map实现。我想将其用作缓存,因此一旦达到限制,就会删除最旧的条目。
我也不想引入对任何第三方库的依赖。
你可以像这样使用LinkedHashMap。
您可以通过 LRU 或 FIFO 进行移除。
public static <K, V> Map<K, V> createLRUMap(final int maxEntries) {
return new LinkedHashMap<K, V>(maxEntries*10/7, 0.7f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > maxEntries;
}
};
}
下面是一个实现,它只是包装一个普通的 HashMap 并将方法调用委托给它。唯一的区别是地图不能增长到超过最大容量。
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
public class CacheMap<K, V> implements Map<K, V> {
private final Map<K, V> delegate = new HashMap<K, V>();
private Queue<K> keyInsertionOrder = new LinkedList<K>();
private final int maxCapacity;
public CacheMap(int maxCapacity) {
if (maxCapacity < 1) {
throw new IllegalArgumentException(
"Capacity must be greater than 0");
}
this.maxCapacity = maxCapacity;
}
@Override
public void clear() {
delegate.clear();
}
@Override
public boolean containsKey(Object key) {
return delegate.containsKey(key);
}
@Override
public boolean containsValue(Object value) {
return delegate.containsValue(value);
}
@Override
public Set<java.util.Map.Entry<K, V>> entrySet() {
return delegate.entrySet();
}
@Override
public boolean equals(Object o) {
return delegate.equals(o);
}
@Override
public V get(Object key) {
return delegate.get(key);
}
@Override
public int hashCode() {
return delegate.hashCode();
}
@Override
public boolean isEmpty() {
return delegate.isEmpty();
}
@Override
public Set<K> keySet() {
return delegate.keySet();
}
@Override
public V put(K key, V value) {
V previous = delegate.put(key, value);
keyInsertionOrder.remove(key);
keyInsertionOrder.add(key);
if (delegate.size() > maxCapacity) {
K oldest = keyInsertionOrder.poll();
delegate.remove(oldest);
}
return previous;
}
@Override
public void putAll(Map<? extends K, ? extends V> m) {
for (K key : m.keySet()) {
put(key, m.get(key));
}
}
@Override
public V remove(Object key) {
keyInsertionOrder.remove(key);
return delegate.remove(key);
}
@Override
public int size() {
return delegate.size();
}
@Override
public Collection<V> values() {
return delegate.values();
}
}