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