Java-defined LRU cache Algorithm
Background
LinkedHashMap inherits from HashMap and provides a removeEldestEntry method. This method is the key to implementing the LRU policy. In addition, HashMap provides three dedicated callback methods for LinkedHashMap, afterNodeAccess, afterNodeInsertion, and afterNodeRemoval methods are literally easy to understand. They are the actions performed after a node is accessed, inserted, and deleted. Based on the above behavior LinkedHashMap, You can implement an LRUCache function.
The eldest of LinkedHashMap: eldest literally indicates the oldest. In LinkedHashMap, there is a segment called accessOrder. When accessOrder is true, it indicates that the nodes in LinkedHashMap are sorted by the number of visits, the oldest node is the node with the least access. When the value of accessOrder is false, it indicates that the inner nodes of hashmap are sorted by the insertion order. The oldest node is the oldest node to be inserted. The default value is false.
Implementation
To implement LRUCache by yourself, you only need to override the removeEldestEntry method. The Code is as follows:
Private static class LRUCache <K, V> extends LinkedHashMap <K, V>
{
Private static final long serialVersionUID =-9111855653176630846L;
Private static int MAX_ELEMENTS;
Public LRUCache (int initCap, int maxSize) throws IllegalArgumentException
{
Super (initCap, 0.75f, true );
If (maxSize <0)
Throw new IllegalArgumentException ();
MAX_ELEMENTS = maxSize;
}
@ Override
Protected boolean removeEldestEntry (Map. Entry <K, V> eldest)
{
Return size ()> MAX_ELEMENTS;
}
}
The above Code requires a MAX_ELEMENTS variable to limit the maximum number of storage nodes. When a node is inserted, it is determined that if the number of the previous nodes exceeds this value, the node with the least access will be deleted according to the LRU policy, note that by default, LinkedHashMap ensures the insertion order, that is, the nodes are sorted by the order of insertion. Therefore, even if you delete a node, the first node to be inserted is deleted, however, we pass in a true value in the constructor. This parameter determines how the segments in the LinkedHashMap are sorted. If the parameter is set to true, the internal nodes are sorted by the last access time, if the value is false, the data is sorted by the insertion order. So far, a simple LRUCache implementation has been completed.
Note:
Because the implementation of LinkedHahsMap itself is not thread-safe, that is to say, this LRUCache is NOT thread-safe. If you want to be able to access multiple threads, you can use it like this: LRUCache cache = Collections. synchronizedMapnew LRUCache (10, 10 )). In this way, the cache can execute get/put operations in multiple threads. However, the cache obtained in this way is not safe in multi-thread time. Therefore, the cache cannot be traversed in multiple threads. We recommend that you use the map itself for synchronization when traversing synchronizedmap.