This article is participating in “Java Theme Month – Java Debug Notes Event”, see < Event link > for more details.
Question: When the limit is reached, how can I limit the maximum size of the Map by removing the oldest element?
I want a Map implementation of the maximum size. I want to use it as a cache, so once the limit is reached, the earliest elements will be deleted.
I also don’t want to introduce any third-party library dependencies.
Answer a
You can use LinkedHashMap like this
You can delete elements via LRU or FIFO.
public static <K, V> Map<K, V> createLRUMap(final int maxEntries) {
return new LinkedHashMap<K, V>(maxEntries*10/7.0.7 f.true) {
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
returnsize() > maxEntries; }}; }Copy the code
Answer two
Here is an implementation that simply wraps a normal HashMap and delegates method calls to it. The only difference is that the Map cannot exceed the maximum capacity.
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(a) {
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(a) {
return delegate.hashCode();
}
@Override
public boolean isEmpty(a) {
return delegate.isEmpty();
}
@Override
public Set<K> keySet(a) {
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(a) {
return delegate.size();
}
@Override
public Collection<V> values(a) {
returndelegate.values(); }}Copy the code
The article translated from Stack Overflow:stackoverflow.com/questions/1…