Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use LinkedHashMap to implement LRU cache

I was trying to implement a LRU cache using LinkedHashMap. In the documentation of LinkedHashMap (http://docs.oracle.com/javase/7/docs/api/java/util/LinkedHashMap.html), it says:

Note that insertion order is not affected if a key is re-inserted into the map.

But when I do the following puts

public class LRUCache<K, V> extends LinkedHashMap<K, V> {     private int size;      public static void main(String[] args) {         LRUCache<Integer, Integer> cache = LRUCache.newInstance(2);         cache.put(1, 1);         cache.put(2, 2);         cache.put(1, 1);         cache.put(3, 3);          System.out.println(cache);     }      private LRUCache(int size) {         super(size, 0.75f, true);         this.size = size;     }      @Override     protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {         return size() > size;     }      public static <K, V> LRUCache<K, V> newInstance(int size) {         return new LRUCache<K, V>(size);     }  } 

The output is

{1=1, 3=3} 

Which indicates that the re-inserted did affected the order. Does anybody know any explanation?

like image 375
Lei Chen Avatar asked Dec 15 '14 00:12

Lei Chen


People also ask

Is LinkedHashMap LRU cache?

Abstract: The LinkedHashMap has an interesting feature, where we can order elements in "access order", rather than the default "insertion order". This allows us to build a light-weight LRU cache.

How will you implement an LRU cache?

To implement an LRU cache we use two data structures: a hashmap and a doubly linked list. A doubly linked list helps in maintaining the eviction order and a hashmap helps with O(1) lookup of cached keys. Here goes the algorithm for LRU cache.

Can we implement LRU cache using queue?

Implementing LRU Cache in Java Queue: Using a doubly-linked list, one can implement a queue where the max size of the queue will be equal to the cache size (the total number of frames that exist).

What is the use of LinkedHashMap in Java?

Answer: The main use of LinkedHashMap in Java is to use it for preserving the insertion order. It can also be used to preserve the access order using which the keys are accessed.


Video Answer


2 Answers

As pointed out by Jeffrey, you are using accessOrder. When you created the LinkedHashMap, the third parameter specify how the order is changed.

"true for access-order, false for insertion-order" 

For more detailed implementation of LRU, you can look at this http://www.programcreek.com/2013/03/leetcode-lru-cache-java/

like image 112
1736964698 Avatar answered Sep 28 '22 17:09

1736964698


But you aren't using insertion order, you're using access order.

order of iteration is the order in which its entries were last accessed, from least-recently accessed to most-recently (access-order)

...

Invoking the put or get method results in an access to the corresponding entry

So this is the state of your cache as you modify it:

    LRUCache<Integer, Integer> cache = LRUCache.newInstance(2);     cache.put(1, 1); // { 1=1 }     cache.put(2, 2); // { 1=1, 2=2 }     cache.put(1, 1); // { 2=2, 1=1 }     cache.put(3, 3); // { 1=1, 3=3 } 
like image 23
Jeffrey Avatar answered Sep 28 '22 17:09

Jeffrey