ConcurrentHashMap.newKeySet() vs Collections.newSetFromMap()

Java 8 引入了获取并发实现的新方法Set

// Pre-Java-8 way to create a concurrent set
Set<String> oldStyle = Collections.newSetFromMap(new ConcurrentHashMap<>());
// New method in Java 8
Set<String> newStyle = ConcurrentHashMap.newKeySet();

有什么理由更喜欢新方法吗?

有什么优点/缺点吗?


答案 1

ConcurrentHashMap.newKeySet()只是比更广泛功能的一部分。Collections.newSetFromMap(new ConcurrentHashMap<>())

如果您看一下这个例子,区别就会变得很明显:

Set<String> set=new ConcurrentHashMap<String,String>().keySet("hello");

现在,在向 中添加新值时,不是映射到您,而是添加值。Boolean.TRUE"hello"Set

这就是为什么返回的 s 的类型为 ConcurrentHashMap.KeySetView 的原因。此类型具有用于请求支持映射以及在添加新键时将使用哪个值的其他方法。Set


因此,虽然看起来与 做同样的事情,但存在语义差异,后者说你不应该在之后使用地图,而前者是设计用于与地图交互的要素的一部分。ConcurrentHashMap.newKeySet()Collections.newSetFromMap(new ConcurrentHashMap<>())

请参阅 Collections.newSetFromMap

调用此方法时,指定的映射必须为空,并且在此方法返回后不应直接访问。

事实上,它甚至没有指定将用于附加值 - 无论如何,你永远不应该处理它......Collections.newSetFromMapBoolean.TRUE


当您想要传递显式请求 .SetConcurrentHashMap.KeySetView


如果您仅使用编译时类型来使用结果,则仍然有可能接收到将使用 /type 强制转换的代码来发现 的结果由 一段时间的结果支持,而 结果不会告诉您。另一方面,这也允许代码以这种方式使用支持映射执行意外操作...SetSetinstanceofConcurrentHashMap.newKeySet()ConcurrentHashMapCollections.newSetFromMap


答案 2

ConcurrentHashMap.newKeySet()应该更有效一些,因为删除了单一级别的间接寻址。 主要基于将操作重定向到 ,但非常接近自身(只是带有附加支持)。Collections.newSetFromMap(map)map.keySet()ConcurrentHashMap.newKeySet()map.keySet()

至于功能,我认为没有区别。


推荐