Guava的LoadingCache怎么不加null值?
How doesn't add null value to Guava's LoadingCache?
我必须使用 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;
}
结果:
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[=11=]0(XpathEvaluator.java:32)
at com.epam.cdatest.parsers.XpathEvaluator.load(XpathEvaluator.java:46)
at com.epam.cdatest.parsers.XpathEvaluator.load(XpathEvaluator.java:43)
xpath值为空时如何避免调用load()
?
如果要区分空 List<String>
和空值,因为 LoadingCache
不支持空值,您可以使用 LoadingCache<String, Optional<List<String>>>
:
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
,这里有 Javadoc, a page in the Wiki,以及 Java 8 的所有文档,现在包括等效的 class.
TL;DR 它是一个包装器,可以测试其内容是否存在:
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
}
我必须使用 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;
}
结果:
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[=11=]0(XpathEvaluator.java:32)
at com.epam.cdatest.parsers.XpathEvaluator.load(XpathEvaluator.java:46)
at com.epam.cdatest.parsers.XpathEvaluator.load(XpathEvaluator.java:43)
xpath值为空时如何避免调用load()
?
如果要区分空 List<String>
和空值,因为 LoadingCache
不支持空值,您可以使用 LoadingCache<String, Optional<List<String>>>
:
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
,这里有 Javadoc, a page in the Wiki,以及 Java 8 的所有文档,现在包括等效的 class.
TL;DR 它是一个包装器,可以测试其内容是否存在:
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
}