I want an implementation of Map that has a maximum size. I want to use this as a cache and so oldest entries are removed once limit has been reached.
I also don't want to introduce a dependency on any 3rd party libraries.
LinkedHashMap. removeEldestEntry() method returns true if this map should remove its eldest entry. This method is invoked by put and putAll after inserting a new entry into the map. It provides the implementor with the opportunity to remove the eldest entry each time a new one is added.
Is there a theoretical limit for the number of key entries that can be stored in a HashMap or does it purely depend on the heapmemory available ? Looking at the documentation of that class, I would say that the theoretical limit is Integer. MAX_VALUE (231-1 = 2147483647) elements.
clear() The clear() method removes all elements from a Map object.
You can use LinkedHashMap like this
You can remove by LRU or 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; } }; }
Here is an implementation that just wraps a normal HashMap and delegates the method calls to it. The only difference is that the Map cannot grow beyond 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() { 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(); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With