您好,欢迎来到12图资源库!分享精神,快乐你我!我们只是素材的搬运工!!
  • 首 页
  • 当前位置:首页 > 开发 > WEB开发 >
    手写最复杂的LRU算法
    时间:2020-09-18 12:07 来源:网络整理 作者:网络 浏览:收藏 挑错 推荐 打印

    LRU(Least recently used)最近最少运用,它的中心思想是“假设数据最近被拜访过,那么未来被拜访的几率也更高”。因此 LRU 算法会依据数据的历史拜访记载来停止排序,假设空间不足,就会淘汰掉最近最少运用的数据。

    2 LRU 完成原理

    由于 LRU 算法会将最近运用的数据优先级上升,因此需求数据结构支持排序,链表十分适宜。

    为什么不思索数组呢?

    由于 LRU 算法,普通都会运用在拜访比较频繁的场景,因此,对数据的移动会频繁,而数组一旦移动,需求将移动到值的位置前面的一切数据的位置全部改动,效率比较低,不引荐运用。

    3 双向链表之LinkedHashMap

    前面我们剖析到 LRU 的算法完成,可以运用链表完成,java 中 LinkedHashMap 就是一个双向链表。

    LinkedHashMap是HashMap的子类,在HashMap数据结构的基础上,还维护着一个双向链表链接一切entry,这个链表定义了迭代顺序,通常是数据插入的顺序。

    我们来看看LinkedHashMap的源码:

    手写最复杂的LRU算法

    从源码中的定义可以看到,accessOrder 属性可以指定遍历 LinkedHashMap 的顺序,true 表示按照拜访顺序,false 表示按照插入顺序,默以为 false。

    由于LRU对拜访顺序敏感,因此运用true来复杂验证一下:

    public class LRUTest { 

        public static void main(String[] args) { 

            LinkedHashMap<String, Object> map = new LinkedHashMap<>(16, 0.75f, true); 

            map.put("a", 1); 

            map.put("b", 2); 

            map.put("c", 3); 

            System.out.println("before get " + map); 

            map.get("a"); 

            System.out.println("after get" + map); 

        }} 

    运转结果如下:

    before get {a=1, b=2, c=3} 

    after get{b=2, c=3, a=1} 

    可以看到经过 accessOrder = true,可以让 LinkedHashMap 按照拜访顺序停止排序。

    那么 LinkedHashMap 是怎样做的呢?

    我们看下get办法

    public V get(Object key) { 

        Node<K,V> e; 

        // 获取node 

        if ((e = getNode(hash(key), key)) == null

            return null

        // 假设 accessOrder = true,则执行afterNodeAccess办法 

        if (accessOrder) 

            afterNodeAccess(e); 

        return e.value; 

    再看下afterNodeAccess办法,发现停止移动节点,到此移动节点的原理我们了解了

    void afterNodeAccess(Node<K,V> e) { // move node to last 

       LinkedHashMap.Entry<K,V> last

       if (accessOrder && (last = tail) != e) { 

           LinkedHashMap.Entry<K,V> p =            (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;        p.after = null;        if (b == null

               head = a;        else 

    (责任编辑:admin)