This is a follow-on qestion from: LRU cache design

Revised Implementation

package lrucache;

import java.util.LinkedHashMap;

public class LRUCacheV2<K, V> extends LinkedHashMap<K, V>{

    private static final int MAX_ENTRIES = 3;
     * super class constructor arguments are
     * cache size = MAX_ENTRIES
     * load factor = 0.75F
     * access order = true
    public LRUCacheV2(){

    protected boolean removeEldestEntry(java.util.Map.Entry<K, V> entry) {
        return size() > MAX_ENTRIES;

    public static void main(String[] args) {
        LRUCacheV2<String, Integer> cache = new LRUCacheV2<String, Integer>();
        cache.put("abc", 1);
        cache.put("def", 2);
        cache.put("ghi", 3);
        cache.put("jkl", 4);
        cache.put("mno", 5);
        cache.put("abc", 1);


{jkl=4, mno=5, abc=1}
  • \$\begingroup\$ Thanks @ratchetfreak. Now i found an easy way to implement LRU cache. Here is the link for LinkedHashMap code. They gave nice explanation link \$\endgroup\$ Feb 11, 2015 at 11:51
  • \$\begingroup\$ I'd prefer composition over inheritance here. \$\endgroup\$
    – guido
    Feb 11, 2015 at 11:56
  • \$\begingroup\$ @guido like this one? \$\endgroup\$ Feb 11, 2015 at 11:59
  • \$\begingroup\$ @ratchetfreak didn't see that code into detail, but definitely yes that's the idea \$\endgroup\$
    – guido
    Feb 11, 2015 at 12:03
  • \$\begingroup\$ @ratchetfreak can somebody please provide me links for locks concept. I want to get some good clarity about locks concept. \$\endgroup\$ Feb 11, 2015 at 12:06

1 Answer 1


Your code looks fine, depending on the use case in which it is applied. A few people have mentioned "composition over inheritance". This is a good point, but it is not directly practical in this situation. You need inheritance in order to get access to the functionality you use in the LinkedHashMap. But, there is an approach where you use inheritance to access the functionality, and composition to expose it.

If you assume the direct approach you have taken is useful for accessing additional functionality from the LinkedHashMap, then your code is good. The variables are well named, the code is consistent (there's a glitch on the one comment line...), and it's all fine.

Whether the hybrid approach is useful to you depends on whether your use case requires just a smallish subset of the the LinkedHashMap functionality. For example, if you needed to access the entries on the content as Map.Entry instances, or if you need to do more complicated iterations, then you start to lose the benefit of the composition.

In this case, the first approach you have using straight inheritance has a place. Th secnd approach requires wrapping the functionality you need from the private inner cache.

This second approach requires tailoring your LRU cache to its specific use cases. At the moment, you have a very general LRU cache. On the other hand, you are only using the put method (and presumably the get()). You can create a class with just these methods (and a selection of other ones that make sense) and gave an internal inherited instance for access to the LinkedHashMap. Consider the following:

public final LRUCacheVC<K,V>() {

    // use inheritence to access LinkedHashMap functionality.
    private static class AccessOrderCache<T,U> extends LinkedHashMap<T,U> {
        private final int capacity;
        AccessOrderCache(final int capacity) {
            super(capacity, 0.75f, true);
            this.capacity = capacity;
        protected boolean removeEldestEntry(java.util.Map.Entry<T, U> entry) {
            return size() > MAX_ENTRIES;

    // Use composition to access the Inherited Cache.    
    private final AccessOrderCache<K,V> cache;

    public LRUCacheVC(final int capacity) {
        cache = new AccessOrderCache<>(capacity);

    public V get(K key) {
        return cache.get(key);

    public V put(K key, V value) {
        return cache.put(key, value)

    public int hashCode() {
        return cache.hashCode();

    public boolean equals(Object other) {
        return other != null 
            && (other instanceof LRUCacheVC)
            && cache.equals(((LRUCacheVC)other).cache);

    public String toString() {
        return cache.toString();

Note how you use inheritence to access the LinkedHashMap concepts, then use composition to incorporate that new class in to your code.

You only expose that limited functionality that you want (get and put), as well as a few other standard methods that make life easier.

  • \$\begingroup\$ thanks a lot. I never think of advantage of inheritance and composition. Now i got some idea where to use inheritance and composition. \$\endgroup\$ Feb 11, 2015 at 16:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.