我尝试使用MapMaker/CacheBuilder创建缓存,但我不明白如何正确处理空值.
ConcurrentMap<Key, Graph> graphs = new MapMaker()
.concurrencyLevel(4)
.weakKeys()
.maximumSize(10000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.makeComputingMap(
new Function<Key, Graph>() {
public Graph apply(Key key) {
return createExpensiveGraph(key);
}
});
Run Code Online (Sandbox Code Playgroud)
如果createExpensiveGraph方法返回null值,则抛出NullpointerException.我不明白为什么ComputingConcurrentHashMap会抛出一个NPE而不是只返回一个空值.
如何妥善处理?只是捕获NPE并返回null?我错过了什么吗?
Lou*_*man 48
番石榴试图强迫你尽可能避免使用null,因为存在的不正当或无证的行为null会导致大量的混乱和错误.我认为尽可能避免使用空值绝对是一个好主意,如果你可以修改你的代码使它不使用null,我强烈推荐这种方法.
您的问题的答案关键取决于"null"值在您的应用程序中实际意味着什么.最有可能的是,这意味着这个密钥"没有价值",或"没有任何东西".在这种情况下,最好的选择是使用.of Optional包装非空值Optional并使用Optional.absent()而不是null.如果必须将其转换为null或非null值,则可以使用Optional.orNull().
Kev*_*ion 12
请注意,即使在您的问题的完整陈述中,您仍然不清楚您的意图是否要缓存该空值.无论CacheBuilder是否决定缓存空值,它都会让许多预期相反的用户感到惊讶.再一次,null造成歧义(这是它最擅长的!).
所以这就是你做的.
是否有可能确定答案将是"空"而没有全部费用createExpensiveGraph?即,真的只是一个简单的前提条件检查吗?如果是这样,你应该在询问缓存之前这样做,此时是否应该缓存结果的问题就会消失.
要缓存空值吗?然后按照路易斯的建议使用Optional<T>.
否则,缓存无法完成为密钥召唤正确值的工作,并且相应的响应是从缓存加载器中抛出异常(如果这是程序员错误,则取消选中,否则检查).这将提供您想要的行为.如果你抛出一个检查过的异常,请确保你在另一边使用Cache.get,而不是Cache.getUnchecked.
| 归档时间: |
|
| 查看次数: |
11961 次 |
| 最近记录: |