简体   繁体   English

LinkedHashMap的最旧条目给出空键,值

[英]LinkedHashMap eldest entry giving null key,value

While trying to use a LinkedHashMap as a LRU cache, I am facing null pointer exceptions. 在尝试将LinkedHashMap用作LRU缓存时,我遇到了空指针异常。 A similar issue was discussed here , however my scenario is a bit different. 这里讨论了类似的问题,但是我的情况有些不同。

@Override
protected boolean removeEldestEntry(Map.Entry<K, CacheItem<V>> eldest)
{
if(size() >= maxEntriesOnHeap)
{
   if (eldest.getValue() != null && eldest.getValue().isExpired(timeToLiveSecs)) 
   {
   offheap.put(eldest.getKey(), eldest.getValue());
   }
   return true;
}

return false;

}

The entry object is a wrapper object. 入口对象是包装对象。 What I found that if I do not provide the null check, it fails intermittently with the 'eldest' entry encountered having null key and null value. 我发现如果不提供空值检查,它会间歇性地失败,并遇到遇到具有空键和空值的“最老”条目。 Proper synchronizations are in place. 适当的同步到位。

So, is anyone aware of a scenario when an entry can exist with both key,value as null? 那么,有人知道键和值都为null的条目可以存在的情况吗?

In a simple test case, this seems to work. 在一个简单的测试案例中,这似乎可行。 Maybe you can point out the differences between this test and your implementation? 也许您可以指出此测试与您的实现之间的区别?

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

public class LinkedHashCacheTest
{
    public static void main(String[] args)
    {
        Map<String, CacheItem<Integer>> map = create();

        map.put("K0", new CacheItem<Integer>(0));
        map.put("K1", new CacheItem<Integer>(1));
        map.put("K2", new CacheItem<Integer>(2));
        map.put("K3", new CacheItem<Integer>(3));
        map.put("K4", new CacheItem<Integer>(4));
        map.put("K5", new CacheItem<Integer>(5));
    }

    static class CacheItem<V>
    {
        V v;
        CacheItem(V v)
        {
            this.v = v;
        }
        public boolean isExpired(double timeToLiveSecs)
        {
            return false;
        }
        @Override
        public String toString()
        {
            return String.valueOf(v);
        }
    }

    static <K, V> Map<K, CacheItem<V>> create()
    {
        Map<K, CacheItem<V>> map = new LinkedHashMap<K, CacheItem<V>>()
        {
            @Override
            protected boolean removeEldestEntry(Map.Entry<K, CacheItem<V>> eldest)
            {
                int maxEntriesOnHeap = 5;
                double timeToLiveSecs = 2;
                if(size() >= maxEntriesOnHeap)
                {
                    System.out.println("Removing   : "+eldest.getKey()+", "+eldest.getValue());
                    if (eldest.getValue().isExpired(timeToLiveSecs)) 
                    {
                        System.out.println("To off-heap: "+eldest.getKey()+", "+eldest.getValue());
                        //offheap.put(eldest.getKey(), eldest.getValue());
                    }
                    return true;
                }

                return false;
            }
        };
        return map;
    }
}

In any case, the question may sound naive, but ... are you sure that there are no null keys used? 无论如何,这个问题听起来很幼稚,但是...您确定没有使用null键吗? A statement like 像这样的声明

map.put(null, value);

will work in the first place... 首先会工作...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM