Skip to content

Instantly share code, notes, and snippets.

@jimexist
Last active August 29, 2015 14:16
Show Gist options
  • Select an option

  • Save jimexist/d028be8688826f37d675 to your computer and use it in GitHub Desktop.

Select an option

Save jimexist/d028be8688826f37d675 to your computer and use it in GitHub Desktop.
LRUCache in Java (not fully tested)
import java.util.HashMap;
import java.util.Map;
public class LRUCache<K, V> {
private final Map<K, Node<K, V>> map;
private final Node<K, V> head, tail;
private final int maxSize;
private static class Node<K, V> {
Node<K, V> next;
Node<K, V> prev;
K key;
V value;
}
public LRUCache(int maxSize) {
assert (maxSize > 0);
this.maxSize = maxSize;
map = new HashMap<>();
head = new Node<>();
tail = new Node<>();
head.next = tail;
tail.prev = head;
}
private Node<K, V> access(K key) {
Node<K, V> node = map.get(key);
if (node != null) {
node.next.prev = node.prev;
node.prev.next = node.next;
node.next = head.next;
node.prev = head;
head.next.prev = node;
head.next = node;
}
return node;
}
public V get(K key) {
Node<K, V> node = access(key);
if (node != null) {
return node.value;
} else {
return null;
}
}
public int size() {
return map.size();
}
public V put(K key, V value) {
Node<K, V> node = access(key);
if (node != null) {
V old = node.value;
node.value = value;
return old;
} else if (size() == maxSize) {
node = tail.prev;
assert node != head : size();
final K oldKey = node.key;
final boolean removed = map.remove(oldKey, node);
assert removed : oldKey;
final V old = node.value;
node.key = key;
node.value = value;
map.put(key, node);
access(key);
return old;
} else {
node = new Node<>();
node.key = key;
node.value = value;
node.next = head.next;
node.prev = head;
head.next.prev = node;
head.next = node;
map.put(key, node);
return null;
}
}
}
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
public class LRUCacheTest {
@Test
public void testGetPut() throws Exception {
List<Integer> li = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
for (int size = 1; size < 10; ++size) {
final LRUCache<Integer, Integer> cache = new LRUCache<>(size);
li.stream().forEach(i -> cache.put(i, i));
assertEquals(size, cache.size());
li.stream().limit(li.size() - size).forEach(i -> assertNull(cache.get(i)));
li.stream().skip(li.size() - size).forEach(i -> assertEquals(i, cache.get(i)));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment