Skip to content

Commit 8b94d0e

Browse files
authored
[impr-LRU-cache] LRU based on LinkedHashMap (#19097)
* [impr-LRU-cache] LRU based on LinkedHashMap * [impr-LRU-cache] lowercase "when ...." * [impr-LRU-cache] add size-assertion
1 parent 5ad3c7f commit 8b94d0e

2 files changed

Lines changed: 73 additions & 0 deletions

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.baeldung.lrucache;
2+
3+
import java.util.LinkedHashMap;
4+
import java.util.Map;
5+
6+
public class LinkedHashMapBasedLRUCache<K,V> extends LinkedHashMap<K,V> {
7+
private final int capacity;
8+
9+
public LinkedHashMapBasedLRUCache(int capacity) {
10+
super(capacity, 0.75f, true);
11+
this.capacity = capacity;
12+
}
13+
14+
@Override
15+
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
16+
return size() > capacity;
17+
}
18+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.baeldung.lrucache;
2+
3+
import static org.junit.Assert.assertEquals;
4+
import static org.junit.Assert.assertFalse;
5+
6+
import java.util.Collections;
7+
import java.util.Map;
8+
import java.util.concurrent.CountDownLatch;
9+
import java.util.concurrent.ExecutorService;
10+
import java.util.concurrent.Executors;
11+
import java.util.stream.IntStream;
12+
13+
import org.junit.Test;
14+
15+
public class LinkedHashMapBasedLRUCacheUnitTest {
16+
17+
@Test
18+
public void whenAddDataToTheCache_ThenLeastRecentlyDataWillEvict() {
19+
LinkedHashMapBasedLRUCache<String, String> lruCache = new LinkedHashMapBasedLRUCache<>(3);
20+
lruCache.put("1", "test1");
21+
lruCache.put("2", "test2");
22+
lruCache.put("3", "test3");
23+
lruCache.put("4", "test4");
24+
25+
assertEquals(3, lruCache.size());
26+
27+
assertFalse(lruCache.containsKey("1"));
28+
29+
assertEquals("test2", lruCache.get("2"));
30+
assertEquals("test3", lruCache.get("3"));
31+
assertEquals("test4", lruCache.get("4"));
32+
}
33+
34+
@Test
35+
public void whenPutDataInConcurrentToCache_ThenNoDataLost() throws Exception {
36+
final int size = 50;
37+
final ExecutorService executorService = Executors.newFixedThreadPool(50);
38+
Map<Integer, String> cache = Collections.synchronizedMap(new LinkedHashMapBasedLRUCache<>(size));
39+
CountDownLatch countDownLatch = new CountDownLatch(size);
40+
try {
41+
IntStream.range(0, size)
42+
.<Runnable> mapToObj(key -> () -> {
43+
cache.put(key, "value" + key);
44+
countDownLatch.countDown();
45+
})
46+
.forEach(executorService::submit);
47+
countDownLatch.await();
48+
} finally {
49+
executorService.shutdown();
50+
}
51+
assertEquals(size, cache.size());
52+
IntStream.range(0, size)
53+
.forEach(i -> assertEquals("value" + i, cache.get(i)));
54+
}
55+
}

0 commit comments

Comments
 (0)