LinkedHashMap 与 LRU

问:简单说说什么是 LRU?

答:LRU 是一种流行的替换算法,它的全称是 Least Recently Used,最近最少使用,常常在缓存设计的场景中充当一种策略,它的核心思路是最近刚被使用的很快再次被用的可能性最高,而最久没被访问的很快再次被用的可能性最低,所以被优先清理。

问:请使用 Java 集合实现一个简约优雅的 LRU 容器?

答:由于 LinkedHashMap 天生支持插入顺序或者访问顺序的 key-value 对,而 LRU 算法的核心恰巧用到它的访问顺序特性,即对一个键执行 get、put 操作后其对应的键值对会移到链表末尾,所以最末尾的是最近访问的,最开始的是最久没被访问的。

LinkedHashMap 有一个 boolean 类型的 accessOrder 参数,当该参数为 true 时则按照元素最后访问时间在双向链表中排序,为 false 则按照插入顺序排序,默认为 false,所以这里需要的操作就是 accessOrder 为 true 的情况。

所以基于 LinkedHashMap 的特性实现的 LRU 容器如下:

        public class LRUCache extends LinkedHashMap {
            private int maxEntries;//maxEntries 最大缓存个数

            public LRUCache(int maxEntries) {
                super(16, 0.75f, true);
                this.maxEntries = maxEntries;
            }

            //在添加元素到LinkedHashMap后会调用这个方法,传递的参数是最久没被访问的键值对,
            // 如果这个方法返回true则这个最久的键值对就会被删除,LinkedHashMap的实现总是返回false,
            // 所以容量没有限制。
            @Override
            protected boolean removeEldestEntry(Entry eldest) {
                return size() > maxEntries;
            }
        }

可以看见实现的简约 LRU 容器核心优雅点就是充分利用了 LinkedHashMap 的有序性特性和容量限制特性。

你可能感兴趣的:(LinkedHashMap 与 LRU)