我们有一个返回HashMap的接口。
现在由于线程安全,我们使用
同步了MapCollections.synchronizedMap(new HashMap());
现在,正在使用我们的接口的客户端面临类
的异常Collections.synchronizedMap返回一个同步的地图,不能转换为哈希地图
我们必须将此synchronizedMap转换回哈希映射
有没有办法转换
返回的synchronizedMapCollections.synchronizedMap()返回哈希映射。
答案 0 :(得分:3)
如果复制是可以接受的(也就是说,您不需要对同步地图进行后续写入以反映在返回的地图中),只需使用HashMap的constructor that takes a Map input即可。确保首先在synchronizedMap上进行同步,因为副本需要在地图上进行迭代(无论如何必须同步)。
synchronized (map) {
return new HashMap<>(map);
}
同步块实际上不是可选的。来自the docs:
当迭代任何集合视图时,用户必须手动同步返回的地图
答案 1 :(得分:1)
不完美,但也许它适用于你的情况:创建一个扩展HashMap的类,但内部有一个同步Map。然后,将所有方法调用委托给内部映射。在构造函数上,创建一个新的HashMap,然后同步它。像这样:
public class SynchronizedHashMap<K, V> extends HashMap<K, V> {
private Map<K, V> internalMap;
public SynchronizedHashMap(int initialCapacity, float loadFactor) {
internalMap = Collections.synchronizedMap(new HashMap<>(initialCapacity, loadFactor));
}
public SynchronizedHashMap(int initialCapacity) {
internalMap = Collections.synchronizedMap(new HashMap<>(initialCapacity));
}
public SynchronizedHashMap() {
internalMap = Collections.synchronizedMap(new HashMap<>());
}
public SynchronizedHashMap(Map<? extends K, ? extends V> m) {
internalMap = Collections.synchronizedMap(new HashMap<>(m));
}
@Override public int size() {
return internalMap.size();
}
@Override public boolean isEmpty() {
return internalMap.isEmpty();
}
@Override public boolean containsKey(Object o) {
return internalMap.containsKey(o);
}
...
}
请记住,这就是为什么你应该编写接口,而不是具体的实现。你的界面应该返回一个Map,你的客户端应该使用Map,而不知道哪个映射它。
答案 2 :(得分:0)
没关系:
Map hashMap = new HashMap();
Map syncMap = Collections.synchronizedMap(hashMap);
HashMap m = new HashMap(syncMap);