LRU cache in Java with Generics and O(1) operations

后端 未结 14 1719
刺人心
刺人心 2020-12-02 07:12

This is a question that comes up a lot in job interviews. The idea is to define a data structure instead of using Java\'s built in LinkedHashMap.

An LRU cache delete

14条回答
  •  生来不讨喜
    2020-12-02 08:04

    Implementation that passes the tests of the leetcode questiton with simple unit tests

    I have made a pull request with this at: https://github.com/haoel/leetcode/pull/90/files

    LRUCache.java

    import java.util.LinkedHashMap;
    import java.util.Iterator;
    
    public class LRUCache {
    
        private int capacity;
        private LinkedHashMap map;
    
        public LRUCache(int capacity) {
            this.capacity = capacity;
            this.map = new LinkedHashMap<>();
        }
    
        public int get(int key) {
            Integer value = this.map.get(key);
            if (value == null) {
                value = -1;
            } else {
                this.set(key, value);
            }
            return value;
        }
    
        public void set(int key, int value) {
            if (this.map.containsKey(key)) {
                this.map.remove(key);
            } else if (this.map.size() == this.capacity) {
                Iterator it = this.map.keySet().iterator();
                it.next();
                it.remove();
            }
            map.put(key, value);
        }
    }
    

    LRUCacheTest.java

    import java.util.ArrayList;
    
    import org.junit.Test;
    import static org.junit.Assert.*;
    
    public class LRUCacheTest {
    
        private LRUCache c;
    
        public LRUCacheTest() {
            this.c = new LRUCache(2);
        }
    
        @Test
        public void testCacheStartsEmpty() {
            assertEquals(c.get(1), -1);
        }
    
        @Test
        public void testSetBelowCapacity() {
            c.set(1, 1);
            assertEquals(c.get(1), 1);
            assertEquals(c.get(2), -1);
            c.set(2, 4);
            assertEquals(c.get(1), 1);
            assertEquals(c.get(2), 4);
        }
    
        @Test
        public void testCapacityReachedOldestRemoved() {
            c.set(1, 1);
            c.set(2, 4);
            c.set(3, 9);
            assertEquals(c.get(1), -1);
            assertEquals(c.get(2), 4);
            assertEquals(c.get(3), 9);
        }
    
        @Test
        public void testGetRenewsEntry() {
            c.set(1, 1);
            c.set(2, 4);
            assertEquals(c.get(1), 1);
            c.set(3, 9);
            assertEquals(c.get(1), 1);
            assertEquals(c.get(2), -1);
            assertEquals(c.get(3), 9);
        }
    }
    

    removeEldestEntry() alternative implementation

    Not sure it is worth it as it takes the same number of lines, but here goes for completeness:

    import java.util.LinkedHashMap;
    import java.util.Iterator;
    import java.util.Map;
    
    class LinkedhashMapWithCapacity extends LinkedHashMap {
        private int capacity;
    
        public LinkedhashMapWithCapacity(int capacity) {
            this.capacity = capacity;
        }
    
        @Override
        protected boolean removeEldestEntry(Map.Entry eldest) {
            return this.size() > this.capacity;
        }
    }
    
    public class LRUCache {
    
        private LinkedhashMapWithCapacity map;
    
        public LRUCache(int capacity) {
            this.map = new LinkedhashMapWithCapacity<>(capacity);
        }
    
        public int get(int key) {
            Integer value = this.map.get(key);
            if (value == null) {
                value = -1;
            } else {
                this.set(key, value);
            }
            return value;
        }
    
        public void set(int key, int value) {
            if (this.map.containsKey(key))
                this.map.remove(key);
            this.map.get(key);
        }
    }
    

提交回复
热议问题