Skip to content

Hashmap using lists as a buffer

I need to create a hashmap that can store multiple values for one key, I know multimaps could do this but I also need to keep those value lists to a specific length. I need a each key to store a list of n values with those being the latest n values, i.e if i reached length n and I add another value the first one added will drop off the value list and the target length is maintained.

I started off the below code and want to change it so i can store/add to a list for a specific key.

       public static void main(final String args[]) throws Exception {
           final int maxSize = 4;
           final LinkedHashMap<String, String> cache = new LinkedHashMap<String, String>() {
           @Override
           protected boolean removeEldestEntry(final Map.Entry eldest) {
               return size() > maxSize;
           }
       };
        cache.put("A", "A");
        System.out.println(cache);
        cache.put("B", "A");
        System.out.println(cache);
        cache.put("C", "A");
        System.out.println(cache);
        cache.put("D", "A");
        System.out.println(cache);
        cache.put("E", "A");
        System.out.println(cache);
        cache.put("F", "A");
        System.out.println(cache);
        cache.put("G", "A");
    }
Output:

    {A=A}
    {A=A, B=A}
    {A=A, B=A, C=A}
    {A=A, B=A, C=A, D=A}
    {B=A, C=A, D=A, E=A}
    {C=A, D=A, E=A, F=A}


I tried changing it to sth like this but can't get it working (python guy here who is getting started with java)

public LinkedHashMap filteroutliers(final String arg, final long arg2) throws Exception{
    final int bufferSize = 5;
    final LinkedHashMap<Integer, ArrayList<Double>> bufferList = new LinkedHashMap<Integer, ArrayList<Double>>(){
        @Override
        protected boolean removeEldestEntry(final Map.Entry eldest){
            return size() < bufferSize;
        }
    };
    return bufferList;
}

Answer

You can extend the HashMap and have your custom map something like this, here I maintained a queue to store the keys so when the limit reaches you can remove the earliest key-value pair (FIFO)

class CacheMap<K, V> extends HashMap<K, V> {

    private static final long serialVersionUID = 1L;
    private int MAX_SIZE;
    private Queue<K> queue = new LinkedList<>();

    public CacheMap(int capacity) {
        super();
        MAX_SIZE = capacity;
    }

    @Override
    public V put(K key, V value) {
        if (super.size() < MAX_SIZE) {
            queue.add(key);
        } else {
            super.remove(queue.poll());
        }
        super.put(key, value);
        return value;
    }
  }
}