LinkedHashMap removeEldestEntry删除2个元素?

时间:2016-05-10 04:22:34

标签: java linkedhashmap

我看了这个帖子:LinkedHashMap removeEldestEntry: How many elements are removed?

它声明removeEldestEntry只删除1个元素。这对我来说很有意义,但是当我通过我的代码调试时,它似乎正在删除2个元素。我不确定为什么。

public class LRUCache {
    LinkedHashMap<Integer, Integer> LRUMap;

    public LRUCache(int capacity) {
        LRUMap = new LinkedHashMap<Integer, Integer>() {
            @Override
            protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
                return LRUMap.size() > capacity;
            }
        };
    }

    public int get(int key) {
        if (LRUMap.containsKey(key)) {
            int val = LRUMap.remove(key);
            LRUMap.put(key,  val);
            return val;
        }
        return -1;
    }

    public void set(int key, int value) {
        LRUMap.put(key, value);
    }

    public static void main(String[] args) {    
        LRUCache c = new LRUCache(2);
        c.set(2,1);
        c.set(1,1);
        c.set(2,3);
        c.set(4,1);
    }
}

因此,您可以看到它将插入:(2,1)(1,1)。下一个因素是事情变得混乱。由于密钥2已存在,因此会使用(2,1)覆盖(2,3)元素。在此之后,当我插入(4,1)时,我已经有2个元素,因此它应该删除最长的条目:(1,1)。但是,它会删除(2,3)(1,1),只留下地图中的(4,1)

任何想法为什么?我认为这与被替换的密钥和(2,3)位于列表的开头有关,就像它是最老的条目一样,即使它不应该。但我仍然困惑为什么它会删除2个元素。

在旁注中,看起来它将最老元素存储在LinkedHashMap的前面,这也可以让我们不断地删除最老的条目。这是真的吗?

1 个答案:

答案 0 :(得分:2)

LinkedHashMap要理解的关键行为特征是地图的Map.Entry<Integer, Integer>成员的目的是为了保留广告订单,它会回答您与之相关的问题Map内成员的排序。因此,如果我们在您的main方法中浏览每行代码,我们会看到以下内容:

  1. c.set(2,1) LRUMap后,{2=1}的内容将为:c.set(1,1)
  2. LRUMap {2=1, 1=1}后,c.set(2,3)的内容将为:LRUMap
  3. {2=3, 1=1} 2后,1的内容将为:3。此操作只是将键(c.set(4,1))的映射值从LRUMap更新为{1=1, 4=1},并且被视为结构更改,因此顺序为成员得到维护。
  4. 2=3 1=1后,LinkedHashMap的内容将为:LinkedHashMap。映射:public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) 被认为是最长的条目,因此它被删除(并且映射:true被保留)。
  5. 由于您的意图很清楚您想要创建一个最近最少使用的缓存,因此您应该考虑更改accessOrder的结构以远离插入订单成员存储,支持 last-access 成员订购。 false类提供了另一种构造函数来支持这种用法:

    accessOrder

    如果为$jsonrows['paymentmethods']['CC']=array() json_encode($jsonrows['paymentmethods']['CC']=array()) 参数传递值"CC":[] ,则成员映射将存储在 access-order 中(这是您要用于LRU缓存)或者如果为"CC":{} 参数传递值 <div> <label> <input type="radio" name="fb" value="small" /> <img src="http://placehold.it/20x20/35d/fff&text=f"> </label> <label> <input type="radio" name="fb" value="big" /> <img src="http://placehold.it/40x60/35d/fff&text=f"> </label> <label> <input id="fb3" type="radio" name="fb" value="med" /> <img src="http://cache1.asset-cache.net/gc/120523070-dogs-gods-gettyimages.jpg?v=1&c=IWSAsset&k=2&d=de2%2btiBrzaNEk9d4xwzh%2fvq8qyKYRsuWlpI1%2f65dmsaBkiniqNTDJkrq7zrUnaC6"> </label> </div> <div> <label> <input type="radio" name="fb" value="small1" text="ss" /> <img src="http://placehold.it/20x20/35d/fff&text=f" text="sdsdsd"> </label> <label> <input type="radio" name="fb" value="big1" /> <img src="http://placehold.it/40x60/35d/fff&text=f"> </label> <label> <input id="fb3" type="radio" name="fb" value="med1" /> <img src="http://cache1.asset-cache.net/gc/120523070-dogs-gods-gettyimages.jpg?v=1&c=IWSAsset&k=2&d=de2%2btiBrzaNEk9d4xwzh%2fvq8qyKYRsuWlpI1%2f65dmsaBkiniqNTDJkrq7zrUnaC6"> </label> </div> ,则成员映射将存储在插入顺序中。