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…