HashMap.containsValue - 有什么作用?

11
我有一个HashMap,需要根据其整数值获取项目。我注意到有一个containsValue()函数,但似乎我仍然必须遍历映射以找到正确的索引。
我的问题是:如果之后仍需要遍历它,为什么要使用containsValue()函数?
此外,我是否完全误解了这个问题?;-)
7个回答

13

一个映射将一个键映射到一个值。如果您有一个值并且知道该映射包含这个值,为什么还需要键呢?

另一方面,如果您确实需要键或者只有值的一个属性,您可以迭代 entrySet(),检查值并在找到时返回键:

for (Map.Entry<Index,Value> entry : map.entrySet()) {
  if (entry.getValue().getXy().equals(xy)) {
    return entry.getKey();
  }
}

7
地图是一个键值存储。说一个值被包含只是作为指示给出的。我认为要想具有双射链接,允许您从值中检索键,您将不得不依赖于像google-collections中的BiMap这样的东西。

4

HashMap(或一般的Map)使用键值对。当您向地图中添加内容时,必须指定一个键,而在检索值时将再次使用该键。基于HashMap的实现,给定一个键,检索值的时间复杂度为O(1)。

containsValue是用于检查HashMap是否包含您要查找的值的有用方法,但我真的不明白为什么要使用它来检索您要查找的值?

使用地图的正确方式应该是:

HashMap<Integer, Object> myMap = new HashMap<Integer, Object>();
myMap.put(1, object1);
myMap.put(2, object2);
myMap.put(3, object3);

现在您可以通过以下方式获取对象:
Object myObject = myMap.get(1);

如果您执行以下操作: myMap.containsValue(1);
这将返回false,因为1是键,而不是值。您可以执行以下操作:
myMap.containsKey(1);

如果您只是想知道它是否存在,但调用没有问题:

Object myObject = myMap.get(99);

如果没有键值,它只会返回null,99。

所以基本上,重点是,你是正确的,在尝试检索值时使用containsValue是没有意义的。如果要先检查存在性,请使用get或containsKey。


4

您不需要在此之后进行遍历。containsValue() 在您不需要精确知道值所在位置,而只需要知道它是否已经存在于Map中的情况下非常有用。如果您需要精确知道值在Map中的位置,请不要使用containsValue() -- 直接跳到迭代器并找到它。


2

在不需要遍历整个哈希表的情况下,您可以使用containsValue()方法。例如,如果您想向哈希表中添加键值对,但在此之前想知道该值是否已经在哈希表中存在,则可以使用该方法。在这种情况下,对于添加操作,您不需要遍历整个哈希表。


2
containsValue()将遍历HashMap:http://www.docjar.com/html/api/java/util/HashMap.java.html#631如果他想知道一个值是否在Map中,这个信息应该保存在一个单独的Set中。 - Christoffer Hammarström
是的,我知道,但他的问题是“为什么要使用containsValue(),如果之后还需要遍历它?”所以我把它翻译成了为什么在之后需要遍历哈希表(第二次)时,containsValue有什么好处。 - sanjuro

2
我认为Map.containsValue在Map接口的设计中是一个错误。
有时我们会遇到提供比线性更快实现containsValue的Map。例如,一种Map可能会将每个不同的值内部表示为小整数,然后使用位模式来表示值集合。这样的Map可以在恒定时间内检测到它以前从未见过的给定值(尽管返回肯定结果可能仍需要线性时间)。
然而,一个有时需要线性时间,有时需要常量时间的操作并不是通用算法的有用基础。你不能用LinkedList替换ArrayList并期望它们都能很好地工作,即使它们两者都支持API中的随机访问。需要恒定时间containsValue的客户端必须维护一个单独的HashSet来保证良好的性能。只需写循环满足线性时间性能的客户端。
即使Map接口的维护者也后悔添加了containsValue,他们当然也无法删除它。"Original Answer"(最初的回答)。

1
让我为Frederik重新阐述这个问题:
containsValue()方法是如何比较哈希表中的每个"value"和其输入参数呢?它是否使用哈希码或其他技术来生成结果?如果是前者,我们可以使用迭代器来遍历并匹配我们的值与哈希表中所有"value"的存在性。问题的重要性在于性能或速度!

我不明白在这种情况下重新构思问题有什么好处。 - andrel
之前的回答与上下文无关。 - Vivek Vardhan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接