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
Here is the java implementation
import java.util.HashMap;
import java.util.Map;
import com.nadeem.app.dsa.adt.Cache;
// Kind of linkedHashMap
public class LRUCache implements Cache {
private int capacity;
private Node head, tail;
private Map> map;
private static final int DEFAULT_CAPACITY = 10;
public LRUCache(int capacity) {
this.capacity = capacity;
this.map = new HashMap>();
}
public LRUCache() {
this(DEFAULT_CAPACITY);
}
@Override
public V get(K key) {
V result = null;
Node node = this.map.get(key);
if (node != null) {
result = node.value;
remove(node);
addAsHead(node);
}
return result;
}
@Override
public void set(K key, V value) {
Node node = this.map.get(key);
if (node == null) {
Node temp = new Node(key, value);
if (this.map.size() < this.capacity) {
addAsHead(temp);
} else {
this.map.remove(this.tail.key);
remove(this.tail);
addAsHead(temp);
}
this.map.put(key, temp);
} else {
node.value = value;
remove(node);
addAsHead(node);
}
}
private void remove(Node node) {
if (node.pre == null) {
this.head = node.next;
} else {
node.pre.next = node.next;
}
if (node.next == null) {
this.tail = node.pre;
} else {
node.next.pre = node.pre;
}
}
private void addAsHead(Node node) {
if (this.head == null) {
this.head = node;
this.tail = node;
} else {
this.head.pre = node;
node.next = this.head;
this.head = node;
}
}
@Override
public void remove(K key) {
Node node = this.map.get(key);
if (node != null) {
this.remove(node);
}
}
private static class Node {
public S key;
public T value;
Node pre;
Node next;
Node(S key, T value) {
this.key = key;
this.value = value;
}
}
@Override
public int size() {
return this.map.size();
}
}
Here is the unit test
public class LRUCacheTest {
private LRUCache cache;
@Before
public void doBeforeEachTestCase() {
this.cache = new LRUCache(2);
}
@Test
public void setTest() {
this.cache.set(1, 1);
assertThat(this.cache.size(), equalTo(1));
assertThat(this.cache.get(1), equalTo(1));
this.cache.set(2, 2);
assertThat(this.cache.size(), equalTo(2));
assertThat(this.cache.get(2), equalTo(2));
this.cache.set(3, 3);
assertThat(this.cache.size(), equalTo(2));
assertThat(this.cache.get(3), equalTo(3));
this.cache.set(1, 3);
assertThat(this.cache.size(), equalTo(2));
assertThat(this.cache.get(1), equalTo(3));
assertThat(this.cache.get(4), equalTo(null));
}
}