Java 它是如何做到的';t向番石榴添加空值';谁在加载缓存?

Java 它是如何做到的';t向番石榴添加空值';谁在加载缓存?,java,xml,caching,xpath,guava,Java,Xml,Caching,Xpath,Guava,我必须使用Guava的LoadingCache将xpath表达式缓存到xpath值 问题在于并非所有XPath都有值。大多数情况下,该值为null 代码段: private LoadingCache<String, List<String>> cachedXpaths = CacheBuilder.newBuilder() .expireAfterWrite(3, TimeUnit.MINUTES) .maximumSize(1000)

我必须使用Guava的
LoadingCache
将xpath表达式缓存到xpath值

问题在于并非所有XPath都有值。大多数情况下,该值为
null

代码段:

private LoadingCache<String, List<String>> cachedXpaths = CacheBuilder.newBuilder()
        .expireAfterWrite(3, TimeUnit.MINUTES)
        .maximumSize(1000)
        .concurrencyLevel(5)
        .weakKeys()
        .build(new CacheLoader<String, List<String>>() {
            @Override
            public List<String> load(String key) throws Exception {
                return createListByKey(key);
            }
        });

private static List<String> createListByKey(String key) throws Exception {
    List<String> values = null;
    try {
        values = instance.getXpathValues(key);
    } catch (XPathExpressionException ignore) {
    }
    return values;
}
private LoadingCache cachedXpaths=CacheBuilder.newBuilder()
.expireAfterWrite(3,时间单位:分钟)
.最大尺寸(1000)
.1级(5)
.weakKeys()
.build(新的缓存加载程序(){
@凌驾
公共列表加载(字符串键)引发异常{
返回createListByKey(键);
}
});
私有静态列表createListByKey(字符串键)引发异常{
列表值=空;
试一试{
values=instance.getXpathValues(键);
}捕获(XPathExpressionException忽略){
}
返回值;
}
结果:

testEncounterSection(com.epam.cdatest.section.EncountersSectionTest)  Time elapsed: 0.002 sec  <<< FAILURE!
com.google.common.util.concurrent.UncheckedExecutionException: com.epam.cdatest.exceptions.XpathHasEmptyValueException
    at com.epam.cdatest.parsers.XpathEvaluator.getXpathValues(XpathEvaluator.java:123)
    at com.epam.cdatest.parsers.XpathEvaluator.createListByKey(XpathEvaluator.java:53)
    at com.epam.cdatest.parsers.XpathEvaluator.access$000(XpathEvaluator.java:32)
    at com.epam.cdatest.parsers.XpathEvaluator$1.load(XpathEvaluator.java:46)
    at com.epam.cdatest.parsers.XpathEvaluator$1.load(XpathEvaluator.java:43)

testEncounterSection(com.epam.cdatest.section.EncountersSectionTest)经过的时间:0.002秒如果要区分空的
列表和空的
列表,因为
LoadingCache
不支持空值,可以使用
LoadingCache

或者(但更丑陋):

List xpath=cachedXpaths.getUnchecked(str.orNull();
if(xpaths!=null){
//用XPath做点什么
}

如果您想区分空的
列表和空的
列表,因为
LoadingCache
不支持空值,您可以使用
LoadingCache

或者(但更丑陋):

List xpath=cachedXpaths.getUnchecked(str.orNull();
if(xpaths!=null){
//用XPath做点什么
}

为什么要避免调用
load()
而不只是返回空列表?事实上,缓存无法知道哪些密钥是不允许的,因此将尝试至少加载一次。加载程序将不得不决定如何处理这些键。@Thomas skip如何返回此空列表?或者如何首先调整缓存以删除空列表?它不会跳过
返回值
调用,但之后缓存将不再加载给定键的值,并始终返回该空列表,这表示该键没有xpath值。除非您确实需要区分“非法”和“那个里什么都并没有”,我建议在这两种情况下都返回一个空列表。@maaartinus若列表的值为空,我想知道这个缓存的效率。与具有某些值的列表相比,此缓存是否会将其删除得更远?你能解释一下吗?为什么要避免调用
load()
,而不只是返回一个空列表?事实上,缓存无法知道哪些密钥是不允许的,因此将尝试至少加载一次。加载程序将不得不决定如何处理这些键。@Thomas skip如何返回此空列表?或者如何首先调整缓存以删除空列表?它不会跳过
返回值
调用,但之后缓存将不再加载给定键的值,并始终返回该空列表,这表示该键没有xpath值。除非您确实需要区分“非法”和“那个里什么都并没有”,我建议在这两种情况下都返回一个空列表。@maaartinus若列表的值为空,我想知道这个缓存的效率。与具有某些值的列表相比,此缓存是否会将其删除得更远?你能解释一下吗?
private LoadingCache<String, Optional<List<String>>> cachedXpaths = CacheBuilder.newBuilder()
        .expireAfterWrite(3, TimeUnit.MINUTES)
        .maximumSize(1000)
        .concurrencyLevel(5)
        .weakKeys()
        .build(new CacheLoader<String, Optional<List<String>>>() {
            @Override
            public Optional<List<String>> load(String key) {
                try {
                    // If getXpathValues() can also return null, use fromNullable()
                    return Optional.of(instance.getXpathValues(key));
                } catch (XPathExpressionException | XpathHasEmptyValueException ignore) {
                    // Maybe log something here as well
                    return Optional.absent();
                }
            }
        });
Optional<List<String>> optionalXpaths = cachedXpaths.getUnchecked(str);
if (optionalXpaths.isPresent()) {
    List<String> xpaths = optionalXpaths.get();
    // Do something with xpaths
}
List<String> xpaths = cachedXpaths.getUnchecked(str).orNull();
if (xpaths != null) {
    // Do something with xpaths
}