Skip to content

Commit 56a527a

Browse files
authored
Merge pull request TheAlgorithms#1385 from varnaa/Development
Added LRU cache implementation.
2 parents 80b765b + 5466ff0 commit 56a527a

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed
+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package com.caching;
2+
3+
4+
import java.util.LinkedHashMap;
5+
import java.util.Map;
6+
import java.util.NoSuchElementException;
7+
8+
/**
9+
* Your LRUCache can be instantiated and called as such:
10+
* LRUCache lruCache = new LRUCache(capacity);
11+
* lruCache.put(key,value);
12+
* int param_1 = lruCache.get(key);
13+
*/
14+
15+
public class LRUCache<T> {
16+
/**
17+
* The class LinkedHashMap,is a subclass of HashMap that preserves the insertion order.
18+
* We can take advantage of this class to avoid having to implement the linked list.
19+
* A special constructor is provided to create a linked hash map whose order of
20+
* iteration is the order in which its entries were least-recently (access-order).
21+
*/
22+
private final LinkedHashMap<Integer, T> cache;
23+
private final int capacity;
24+
25+
/**
26+
* @param capacity - Instantiates LRUCache with the given capacity.
27+
*/
28+
public LRUCache(int capacity) {
29+
this.capacity = capacity;
30+
31+
/*
32+
@param loadFactor Load Factor is a measure, which decides when exactly to resize the
33+
* HashMap. By default capacity = 16 and loadFactor = 0.75f. This means
34+
* that reisze when HashMap reaches 75% of its capacity. For we will
35+
* remove an element only if the cache reaches 100% capacity (1.0f).
36+
*
37+
* @param accessOrder - Set to true if ordering mode is specified (removeEldestEntry).
38+
*/
39+
this.cache = new LinkedHashMap<>(capacity, 1.0f, true) {
40+
/**
41+
* @param eldest - The least recently accessed entry This is the entry that will
42+
* be removed if the method returns {@code true}.
43+
* returns {@code false} if it should be retained.
44+
*/
45+
@Override
46+
protected boolean removeEldestEntry(Map.Entry eldest) {
47+
return this.size() > capacity;
48+
}
49+
};
50+
}
51+
52+
53+
/**
54+
* To put a value in LRU cache with corresponding key
55+
* We add the value for key only if the key is not present.
56+
* We don't update existing values, only access-order is updated.
57+
*
58+
* @param key The key (int)
59+
* @param value The value to be cached
60+
*/
61+
public void put(int key, T value) {
62+
if (capacity == 0) {
63+
System.out.println("Cache set to 0 capacity. No elements will be cached");
64+
}
65+
66+
T currentValue = cache.get(key);
67+
if (!cache.containsKey(key)) {
68+
cache.put(key, value);
69+
System.out.println("Adding new key:" + key + " to cache");
70+
} else {
71+
System.out.println("Key:" + key + " already present in cache. Access order will be updated.");
72+
}
73+
}
74+
75+
76+
/**
77+
* To get the cached value for given key
78+
*
79+
* @param key The key (int) of the expected value
80+
* @return corresponding value for input key
81+
* @throws NoSuchElementException if key is absent
82+
*/
83+
public T get(int key) {
84+
// cache hit condition
85+
if (cache.containsKey(key)) {
86+
T value = cache.get(key);
87+
System.out.println("Returning value from cache:" + value);
88+
return value;
89+
}
90+
// cache miss condition
91+
throw new NoSuchElementException("No element found for key:" + key);
92+
}
93+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.caching;
2+
3+
import org.junit.jupiter.api.Assertions;
4+
import org.junit.jupiter.api.Test;
5+
6+
import java.util.NoSuchElementException;
7+
8+
public class LRUCacheTest {
9+
10+
@Test
11+
public void testLFUCache() {
12+
LRUCache<Integer> cache = new LRUCache<Integer>(2);
13+
14+
cache.put(1, 5);
15+
cache.put(2, 4);
16+
Assertions.assertEquals(5, cache.get(1)); // returns 5
17+
cache.put(3, 6); // evicts key 2
18+
Assertions.assertThrows(NoSuchElementException.class, () -> cache.get(7));// throws exception
19+
Assertions.assertEquals(6, cache.get(3)); // returns 6.
20+
cache.put(4, 8); // evicts key 1.
21+
Assertions.assertThrows(NoSuchElementException.class, () -> cache.get(1));// throws exception
22+
Assertions.assertEquals(6, cache.get(3)); // returns 6
23+
Assertions.assertEquals(8, cache.get(4)); // returns 8
24+
}
25+
}

0 commit comments

Comments
 (0)