ConcurrentHashMap.newKeySet()vs Collections.newSetFromMap()

tur*_*off 15 java set concurrenthashmap java.util.concurrent java-8

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();
Run Code Online (Sandbox Code Playgroud)

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

有什么优点/缺点?

Hol*_*ger 12

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

如果你看一下这个例子,差异就会变得清晰:

Set<String> set=new ConcurrentHashMap<String,String>().keySet("hello");
Run Code Online (Sandbox Code Playgroud)

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

这就是返回的Sets具有类型的原因ConcurrentHashMap.KeySetView.此类型还有其他方法可用于请求支持映射以及添加新键时将使用的值.


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

Collections.newSetFromMap:

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

事实上,它甚至不指定Collections.newSetFromMap将使用Boolean.TRUE的附加值,你永远不应该与处理反正...


当您想要传递Set给显式请求的代码时,它也可能很有用ConcurrentHashMap.KeySetView.


如果您仅使用编译时类型使用结果Set,则仍然有可能接收到的代码Set将使用instanceof/类型强制转换来查明结果ConcurrentHashMap.newKeySet()是否支持一段ConcurrentHashMap时间结果Collections.newSetFromMap不会告诉您.另一方面,这也允许代码以支持地图的方式执行意外的事情......

  • 虽然这是真的,我看不出这个功能如何用于`ConcurrentHashMap.newKeySet()`... (3认同)

Tag*_*eev 7

ConcurrentHashMap.newKeySet()应该更有效率,因为删除单个级别的间接.Collections.newSetFromMap(map)主要是基于将操作重定向到map.keySet(),但ConcurrentHashMap.newKeySet()非常接近map.keySet()自己(只需添加支持).

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

  • @turbanoff,`KeySetView`将其方法委托给地图,但`newSetFromMap`首先将其方法委托给keySet方法,而keySet方法又将它们委托给地图.这就是为什么它的间接水平较低. (2认同)