标签:cto style lin bsp 调用 ted his 排序 not
LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”
距离现在最早使用的会被我们替换掉。不够形象的话我们看下面的例子。
size=3的缓存淘汰实现:
在插入元素1的时候,位置1、2、3依次为1、null、null
在插入元素2的时候,位置1、2、3依次为1、2、null
....
在插入元素4的时候,位置1、2、3依次为2、3、4,本来位置1的元素1被淘汰
import java.util.LinkedHashMap; import java.util.Map; public class UseLinkedHashMapCache<K,V> extends LinkedHashMap<K,V> { private int cacheSize; public UseLinkedHashMapCache(int cacheSize) { //参数依次为初始容量,负载因子,排序模式 super(16, 0.75f, true); this.cacheSize = cacheSize; } @Override protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { return size() > cacheSize; //临界条件不能有等于,否则会让缓存尺寸小1 } }
看一下LinkedHashMap的构造方法:
/** * Constructs an empty <tt>LinkedHashMap</tt> instance with the * specified initial capacity, load factor and ordering mode. * * @param initialCapacity the initial capacity * @param loadFactor the load factor * @param accessOrder the ordering mode - <tt>true</tt> for * access-order, <tt>false</tt> for insertion-order * @throws IllegalArgumentException if the initial capacity is negative * or the load factor is nonpositive */ public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) { super(initialCapacity, loadFactor); this.accessOrder = accessOrder; }
accessOrder有两种模式,如果设置为true的话是按照访问排序,设置是false的话是按照插入顺序排序
然后在看一下我们重写的removeEldestEntry方法:
/** * Returns <tt>true</tt> if this map should remove its eldest entry. * This method is invoked by <tt>put</tt> and <tt>putAll</tt> after * inserting a new entry into the map. It provides the implementor * with the opportunity to remove the eldest entry each time a new one * is added. This is useful if the map represents a cache: it allows * the map to reduce memory consumption by deleting stale entries. * * <p>Sample use: this override will allow the map to grow up to 100 * entries and then delete the eldest entry each time a new entry is * added, maintaining a steady state of 100 entries. * <pre> * private static final int MAX_ENTRIES = 100; * * protected boolean removeEldestEntry(Map.Entry eldest) { * return size() > MAX_ENTRIES; * } * </pre> * * <p>This method typically does not modify the map in any way, * instead allowing the map to modify itself as directed by its * return value. It <i>is</i> permitted for this method to modify * the map directly, but if it does so, it <i>must</i> return * <tt>false</tt> (indicating that the map should not attempt any * further modification). The effects of returning <tt>true</tt> * after modifying the map from within this method are unspecified. * * <p>This implementation merely returns <tt>false</tt> (so that this * map acts like a normal map - the eldest element is never removed). * * @param eldest The least recently inserted entry in the map, or if * this is an access-ordered map, the least recently accessed * entry. This is the entry that will be removed it this * method returns <tt>true</tt>. If the map was empty prior * to the <tt>put</tt> or <tt>putAll</tt> invocation resulting * in this invocation, this will be the entry that was just * inserted; in other words, if the map contains a single * entry, the eldest entry is also the newest. * @return <tt>true</tt> if the eldest entry should be removed * from the map; <tt>false</tt> if it should be retained. */ protected boolean removeEldestEntry(Map.Entry<K,V> eldest) { return false; }
在每次插入元素(put或者putAll)会调用该方法,如果返回true的话,则会删除该map的最早插入的那个元素。所以当这个map要作为缓存的时候,在map存储不下更多的元素时候,把最老的那个元素删除来减少内存消耗
public class TestLRU { public static void main(String[] args) { UseLinkedHashMapCache<Integer,String> cache = new UseLinkedHashMapCache<>(4); cache.put(1, "one"); cache.put(2, "two"); cache.put(3, "three"); cache.put(4, "four"); cache.put(2, "two");for (Integer key : cache.keySet()) { System.out.println("Key:\t"+key); } } }
输出结果(按照访问顺序来淘汰):
Key: 1 Key: 3 Key: 4 Key: 2
然后把之前构造方法中的accessOrder模式改为false(也就是按插入顺序来淘汰)
输出结果:
Key: 1 Key: 2 Key: 3 Key: 4
整理自:
https://blog.csdn.net/nakiri_arisu/article/details/79205660
https://blog.csdn.net/u012485480/article/details/82427037
标签:cto style lin bsp 调用 ted his 排序 not
原文地址:https://www.cnblogs.com/zz-ksw/p/12425565.html