Java 集合 LinkedHashMap 与 LRU cache

更多 Java 集合类方面的文章,请参见文集《Java 集合类》


LRU - Least Recent Used

最近最少使用原则。
可以通过使用 LinkedHashMap 来实现,原因:

  • LinkedHashMap 遍历时按照插入的顺序或者访问的顺序。
    • 此处我们使用按照 访问的顺序 来遍历,即最近访问的元素会出现在遍历的最前面:
// 将第三个参数 accessOrder 设置为 true
new LinkedHashMap(hashTableCapacity, hashTableLoadFactor, true);
  • LinkedHashMap 本身有一个方法用于判断是否需要移除最不常读取的数,默认不需要移除:
    protected boolean removeEldestEntry(Map.Entry eldest) {
        return false;
    }
  • 此处我们需要根据 cache 的容量来重写该方法,将最近不常使用的元素移除,例如
protected boolean removeEldestEntry(Map.Entry eldest) {
    return size() > LRUCache.this.cacheSize;
}

完整例子:

public class LRUCache {
    private static final float hashTableLoadFactor = 0.75f;
    private LinkedHashMap map;
    private int cacheSize;

    /**
     * Creates a new LRU cache. 在该方法中,new LinkedHashMap(hashTableCapacity,
     * hashTableLoadFactor, true)中,true代表使用访问顺序
     */
    public LRUCache(int cacheSize) {
        this.cacheSize = cacheSize;
        int hashTableCapacity = (int) Math
                .ceil(cacheSize / hashTableLoadFactor) + 1;

        map = new LinkedHashMap(hashTableCapacity, hashTableLoadFactor,
                true) {
            // (an anonymous inner class)
            private static final long serialVersionUID = 1;

            @Override
            protected boolean removeEldestEntry(Map.Entry eldest) {
                return size() > LRUCache.this.cacheSize;
            }
        };
    }

    public synchronized V get(K key) {
        return map.get(key);
    }

    public synchronized void put(K key, V value) {
        map.put(key, value);
    }

    public synchronized Collection> getAll() {
        return new ArrayList>(map.entrySet());
    }
}

引用:
LinkedHashMap 与 LRUcache

你可能感兴趣的:(Java 集合 LinkedHashMap 与 LRU cache)