1

1. LRU是什么

LRU=Least Recently Used 最近最少使用淘汰算法(首先淘汰最长时间未被使用的页面)

2. LRU和LinkedHashMap的联系

2.1 accessOrder属性

true则按照访问顺序安排迭代顺序; false则按照插入顺序来安排迭代顺序;

    /**
     * The iteration ordering method for this linked hash map: 
     * true for access-order, false for insertion-order.
     */
    final boolean accessOrder;

2.2 构造方法

LinkedHashMap有一个构造方法, 可以传递一个参数accessOrder, 设置为true, 可以直接调整迭代出的顺序, 最近常使用的, 会排到最后, 最不常使用的, 放到最前面, 如果size()撑爆, 就开始砍最前面使用少的; 达到LRU的效果;

/** 
 * 构造一个空的LinkedHashMap实例,该实例具有指定的初始容量、装载因子和排序模式。
 */
public LinkedHashMap(int initialCapacity,
                     float loadFactor,
                     boolean accessOrder) {
    super(initialCapacity, loadFactor);
    this.accessOrder = accessOrder;
}

3. LRU的LinkedHashMap实现:

3.1 实现代码

package com.niewj.dsalg;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * LRU算法简单实现-通过 LinkedHashMap 来实现
 * Created by niewj on 2020/8/15 8:51
 */
public class LRUCache<K, V> {
    private final LinkedHashMap<K, V> cache;

    public LRUCache(final int maxSize) {
        this.cache = new LinkedHashMap<K, V>(16, 0.75F, true) {
            @Override
            protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
                return size() > maxSize;
            }
        };
    }

    public void put(K key, V value) {
        this.cache.put(key, value);
    }

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

    public V remove(K key) {
        return this.cache.remove(key);
    }

    public static void main(String[] args) {
        LRUCache lruCache = new LRUCache(128);
        for (int i = 0; i < 150; i++) {
            lruCache.put(i + "", i);

            if (i >= 127) {
                // 如果大于容量, 我们遍历前128个里面能被5整除的所有数一遍; 最后检查map内容, 看被移除的是不是5/0结尾的会避免
                for (int i1 = 0; i1 < i; i1++) {
                    if (i1 % 5 == 0) {
                        System.out.print(lruCache.get(i1 + "") + "\t");
                    }
                }
                System.out.println("-----------");
            }
        }

        System.out.println(" -- 下面是打印出的cache中的数据");
        System.out.println(lruCache.cache);
    }
}

3.2 main方法的输出

0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    130    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    130    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    130    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    130    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    130    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    130    135    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    130    135    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    130    135    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    130    135    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    130    135    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    130    135    140    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    130    135    140    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    130    135    140    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    130    135    140    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    130    135    140    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    130    135    140    145    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    130    135    140    145    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    130    135    140    145    -----------
0    5    10    15    20    25    30    35    40    45    50    55    60    65    70    75    80    85    90    95    100    105    110    115    120    125    130    135    140    145    -----------
-- 下面是打印出的cache中的数据
{28=28, 29=29, 31=31, 32=32, 33=33, 34=34, 36=36, 37=37, 38=38, 39=39, 41=41, 42=42, 43=43, 44=44, 46=46, 47=47, 48=48, 49=49, 51=51, 52=52, 53=53, 54=54, 56=56, 57=57, 58=58, 59=59, 61=61, 62=62, 63=63, 64=64, 66=66, 67=67, 68=68, 69=69, 71=71, 72=72, 73=73, 74=74, 76=76, 77=77, 78=78, 79=79, 81=81, 82=82, 83=83, 84=84, 86=86, 87=87, 88=88, 89=89, 91=91, 92=92, 93=93, 94=94, 96=96, 97=97, 98=98, 99=99, 101=101, 102=102, 103=103, 104=104, 106=106, 107=107, 108=108, 109=109, 111=111, 112=112, 113=113, 114=114, 116=116, 117=117, 118=118, 119=119, 121=121, 122=122, 123=123, 124=124, 126=126, 127=127, 128=128, 129=129, 131=131, 132=132, 133=133, 134=134, 136=136, 137=137, 138=138, 139=139, 141=141, 142=142, 143=143, 144=144, 146=146, 147=147, 148=148, 149=149, 0=0, 5=5, 10=10, 15=15, 20=20, 25=25, 30=30, 35=35, 40=40, 45=45, 50=50, 55=55, 60=60, 65=65, 70=70, 75=75, 80=80, 85=85, 90=90, 95=95, 100=100, 105=105, 110=110, 115=115, 120=120, 125=125, 130=130, 135=135, 140=140, 145=145}

可以看到, 28之前的所有元素都被清除了(除了我们访问过的5的倍数的元素), 可见最先插入的元素, 如果没有使用过, 等到满足条件 size() > maxSize 就会被清理;

核心就在于LinkedHashMap的@Override的方法removeEldestEntry:

    public LRUCache(final int maxSize) {
        this.cache = new LinkedHashMap<K, V>(16, 0.75F, true) {
            @Override
            protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
                return size() > maxSize;
            }
        };
    }

4. LRU-LinkedHashMap小结

4.1 boolean字段accessOrder

4.2 三参构造方法

LinkedHashMap(initialCapacity, loadFactor, accessOrder)

4.3 重写removeEldestEntry方法

@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
    return size() > maxSize;
}

丰木
322 声望19 粉丝

遇见超乎想象的自己!


引用和评论

0 条评论