关于方法返回的Map vs List细节

时间:2016-06-15 11:40:08

标签: java list dictionary set duplicates

如果我有一些实例变量,那么就说

private Map<String,MyClass> myMap;

如果我想创建一个返回myMap键的方法,我是否必须保证该方法返回一个Set(不具有重复项)或者是否已经由实例变量定义保证了?如果我决定从方法中返回List类型,是否有任何重复的情况(我相信List比设置更有效)?

亮点

public List<String> myKeys(){
    return
       myMap.keySet().stream().collect(Collectors.toList());
} 

 public Set<String> myKeys(){
    return
       myMap.keySet().stream().collect(Collectors.toSet());
} 

就:

而言
  1. 重复存在;
  2. 性能。

    **

  3. 编辑:小错误。我只想问一下keySet()。

    **

7 个答案:

答案 0 :(得分:0)

如果是关于价值观的话:当然我们可以在那里重复。

没有人阻止我输入像

这样的东西
1, "foo"
2, "bar"
3, "foo"

进入地图。

因此,虽然密钥可以表示为Set,但值可以是&#39; t。

答案 1 :(得分:0)

Map无法在密钥上重复。

来自javadoc

  

将键映射到值的对象。地图不能包含重复的密钥;每个键最多可以映射一个值。

Map可以有重复的值。

答案 2 :(得分:0)

地图的键始终是唯一的,值可能包含重复项。如果您将值收集到一个集合中,您将不会有重复项。如果你收集到一个列表,你可能有重复。

但是当你使用克隆时,你最终可能会得到有效的重复项,即使是在一个集合中。

关于表现,两种方式应该或多或少相等。

答案 3 :(得分:0)

Map是一个界面,您可以按照自己喜欢的方式实现它。

但是,您可能希望遵循Map接口的常见假设行为,以免混淆可能使用您的代码的其他程序员。

答案 4 :(得分:0)

这取决于你的需求。 List上的后续修改操作不能保证您的集合不会包含重复项,而Set上的此类操作将会执行此操作。

就性能而言,Collections.toSet的合同保证Set,实施(JDK / OpenJDK)选择HashSet

因此,您必须决定(取决于要执行的后续操作)是否应使用HashSetList

您可以根据时间复杂度或空间做出决定,您应该使用Big O作弊表,您可以在此处找到:BigO Cheat Sheet

答案 5 :(得分:0)

  • java.util.Collection:集合层次结构中的通用根接口。
  • java.util.Set:阻止插入重复元素的集合。
  • java.util.List:当需要以某个用户定义的顺序检索元素时使用的集合。

答案 6 :(得分:0)

在Java中,至少在OpenJDK中,HashSet实际上是使用HashMap实现的。具体来说,Map的键形成Set,其中元素是唯一的。

另一方面,

List s是有序序列,可能具有重复元素。 Map的值不会形成Set,而是List

然而,您可以将List的重复元素放在Set内,这是您使用Collectors.toSet获得的内容。

Collectors.toListCollectors.toSet的实施将为您提供ArrayListHashSet。如果您知道索引(随机访问),前者提供快速查找,因此在迭代数组时具有高性能(这是由于现代CPU的工作方式,数据局部性很重要......在这种情况下,Big-O-复杂性可能无法反映现实世界的情景)。后者主要提供快速搜索,即:“x属于这个集合吗?”

所以我们有:

  • 设置:无重复,通常无序,快contains(...) ...
  • 列表:有序序列,可能有重复,(在数组的情况下)快速迭代。

Set可以实现为树而不是散列映射。并且List可以实现为链接列表。但是你使用的功能没有,所以你应该真正考虑Set中的ListHash Table以及http://bigocheatsheet.com/中的Arraycollect

顺便说一句:如果我没有弄错的话,myMap.values()实际上会做一个隐式副本,因此此时List的视图不再存在,并且后续修改结果Set 1}} / Map也未在angular2-in-memory-web-api中完成。