在Java中,我经常需要懒洋洋地获取ConcurrentMap的条目,仅在必要时创建。
例如我可能有
ConcurrentMap<String, AtomicReference<Something>> a = new ConcurrentHashMap<>();
ConcurrentMap<String, Something> b = new ConcurrentHashMap<>();
我想创建一个通用函数来完成这项工作,这样我就不会为每种类型重复the rather cumbersome double checking code。
以下是我能得到的:
<K, V, C extends V> V ensureEntry(ConcurrentMap<K, V> map, K key, Class<? super C> clazz) throws Exception {
V result = map.get(key);
if (result == null) {
final V value = (V)clazz.newInstance();
result = map.putIfAbsent(key, value);
if (result == null) {
result = value;
}
}
return result;
}
然后我就可以使用它了:
AtomicReference<Something> ref = ensureElement(a, "key", AtomicReference.class);
Something something = ensureElement(b, "another key", Something.class);
问题是:该函数非常脏,并且仍然存在不安全的泛型类转换((V)
)。一个完全通用和清洁的可能吗?也许在斯卡拉?
谢谢!
答案 0 :(得分:2)
使用Java 8 lambda,以下是我能得到的最简单的...
<K, V> V ensureEntry(ConcurrentMap<K, V> map, K key, Supplier<V> factory) {
V result = map.get(key);
if (result == null) {
V value = factory.get();
result = map.putIfAbsent(key, value);
if (result == null) {
result = value;
}
}
return result;
}
ConcurrentMap<String, AtomicReference<Object>> map = new ConcurrentHashMap<>();
ensureEntry(map, "key", () -> new AtomicReference<>());
// or
ensureEntry(map, "key", AtomicReference::new);