LinkedHashSet to implement LRU
Asked Answered
S

2

11

I want to remove the oldest member of a LinkedHashSet , I know that there's a removeEldestEntry method that I have to override (Java doc for removeEldestEntry ), but I guess that I have to define initial capacity and load factor which I don't care and I simply want to remove the element which was least recently accessed (here by access I mean being put while it's already in the set or being read)

Is there any way not to override removeEldestEntry ?

Supinate answered 22/6, 2013 at 21:39 Comment(0)
H
32

I know that there's a removeEldestEntry method that I have to override

This statement is wrong since LinkedHashSet HAS-A LinkedHashMap and not IS-A.

You could use the useful (although not well known), Collections.newSetFromMap method:

Set<String> mySet = Collections.newSetFromMap(new LinkedHashMap<String, Boolean>(){
    protected boolean removeEldestEntry(Map.Entry<String, Boolean> eldest) {
        return size() > MAX_ENTRIES;
    }
});

It will thus return a Set vision of a LinkedHashMap (a Set-Like interface) implementing your custom removeEldestEntry method.

MAX_ENTRIES being a custom constant that you would have defined.

Heiskell answered 22/6, 2013 at 22:10 Comment(1)
That's brilliant! Now with Java 13 and up, is there any other way to create a LRU set?Speer
W
0

Slight enhancement to the above answer:

    Collections.newSetFromMap(new LinkedHashMap<T, Boolean>(maxSize, 0.75f, true) {  

      @Override
      public boolean containsKey(Object key) {
       // Unfortunately, the LinkedHashMap containsKey method doesn't reset the LRU order, 
       // so perform a 'get' call here too
        return super.containsKey(key)
                && super.get(key); 
      }

      @Override
      protected boolean removeEldestEntry(Map.Entry<T, Boolean> eldest) {
        return this.size() > maxSize;
      }
    });
Weigand answered 27/9, 2022 at 19:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.