Easy, simple to use LRU cache in java Easy, simple to use LRU cache in java java java

Easy, simple to use LRU cache in java


You can use a LinkedHashMap (Java 1.4+) :

// Create cachefinal int MAX_ENTRIES = 100;Map cache = new LinkedHashMap(MAX_ENTRIES+1, .75F, true) {    // This method is called just after a new entry has been added    public boolean removeEldestEntry(Map.Entry eldest) {        return size() > MAX_ENTRIES;    }};// Add to cacheObject key = "key";cache.put(key, object);// Get objectObject o = cache.get(key);if (o == null && !cache.containsKey(key)) {    // Object not in cache. If null is not a possible value in the cache,    // the call to cache.contains(key) is not needed}// If the cache is to be used by multiple threads,// the cache must be wrapped with code to synchronize the methodscache = (Map)Collections.synchronizedMap(cache);


This is an old question, but for posterity I wanted to list ConcurrentLinkedHashMap, which is thread safe, unlike LRUMap. Usage is quite easy:

ConcurrentMap<K, V> cache = new ConcurrentLinkedHashMap.Builder<K, V>()    .maximumWeightedCapacity(1000)    .build();

And the documentation has some good examples, like how to make the LRU cache size-based instead of number-of-items based.


Here is my implementation which lets me keep an optimal number of elements in memory.

The point is that I do not need to keep track of what objects are currently being used since I'm using a combination of a LinkedHashMap for the MRU objects and a WeakHashMap for the LRU objects.So the cache capacity is no less than MRU size plus whatever the GC lets me keep. Whenever objects fall off the MRU they go to the LRU for as long as the GC will have them.

public class Cache<K,V> {final Map<K,V> MRUdata;final Map<K,V> LRUdata;public Cache(final int capacity){    LRUdata = new WeakHashMap<K, V>();    MRUdata = new LinkedHashMap<K, V>(capacity+1, 1.0f, true) {        protected boolean removeEldestEntry(Map.Entry<K,V> entry)        {            if (this.size() > capacity) {                LRUdata.put(entry.getKey(), entry.getValue());                return true;            }            return false;        };    };}public synchronized V tryGet(K key){    V value = MRUdata.get(key);    if (value!=null)        return value;    value = LRUdata.get(key);    if (value!=null) {        LRUdata.remove(key);        MRUdata.put(key, value);    }    return value;}public synchronized void set(K key, V value){    LRUdata.remove(key);    MRUdata.put(key, value);}}