如何将Collections.synchronizedMap(new HashMap())转换为Hash Map

时间:2015-10-20 08:26:28

标签: java collections

我们有一个返回HashMap的接口。

现在由于线程安全,我们使用

同步了Map

Collections.synchronizedMap(new HashMap());

现在,正在使用我们的接口的客户端面临类

的异常

Collections.synchronizedMap返回一个同步的地图,不能转换为哈希地图

我们必须将此synchronizedMap转换回哈希映射

有没有办法转换

返回的synchronizedMap

Collections.synchronizedMap()返回哈希映射。

3 个答案:

答案 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);