使用HashMap支持的contains()方法的Set的准确性?

时间:2012-09-08 02:38:54

标签: java hashmap set hashcode hash-code-uniqueness

您好我正在使用由HashMap支持的Set来跟踪我在图表中已经遍历的边缘。 我计划通过添加存储在每个边缘的数据的哈希码来键入该集合。

v.getData().hashCode() + wordV.getData().hashCode()

但是当使用contains检查边缘是否在集合中时,这有多可靠?我不能假设得到误报吗?无论如何要克服这个问题吗?

引起我关注的确切陈述是:

edgeSet.contains(v.getData().hashCode() + wordV.getData().hashCode())

谢谢!

哦,就像我使用Java一样。

编辑:

我应该在问题中明确这一点。在我的图形中没有边缘对象,有顶点对象,每个顶点对象包含更多顶点对象的列表,即边缘。因此,我认为结合您的回答后面的问题是:

我可以使用Set来存储信息的引用而不是对象....? 即我可以存储为顶点的数据对象添加两个哈希码的结果吗?

EDIT2:

我确实在我的hashmap中使用Java库,我将其声明如下:

Set<Integer> edgeSet = Collections.newSetFromMap(new ConcurrentHashMap<Integer, Boolean>());

3 个答案:

答案 0 :(得分:6)

注意:根据您的问题,我无法判断您是使用HashSet还是自己的家庭滚动实施。请注意,Java的HashSet只是HashMap的包装器,其中值被忽略。 HashSet.contains只需在内部地图上调用containsKey

HashMap.containsKey使用与get相同的查找。这将计算哈希值并使用它来查找正确的桶。从那里它将走在桶中并使用equals直到找到完全匹配。假设元素类型正确地实现了hashCodeequals,那么使用containsKey就不会产生误报,因为equals最终用于确认。

relevant source code位于包私有方法getEntry中,由containsKeyget使用:

final Entry<K,V> getEntry(Object key) {
    int hash = (key == null) ? 0 : hash(key.hashCode());
    for (Entry<K,V> e = table[indexFor(hash, table.length)];
         e != null;
         e = e.next) {
        Object k;
        if (e.hash == hash &&
            ((k = e.key) == key || (key != null && key.equals(k))))
            return e;
    }
    return null;
}

修改

  

我可以使用Set来存储对信息的引用,而不是   对象....?即我可以存储添加两个哈希码的结果   顶点的数据对象?

不,您需要实现一个表示此信息的新类,并将其实例存储在Set中。这可以是一个简单的POJO,其中包含每条信息的字段,并且正确覆盖hashCodeequals

答案 1 :(得分:5)

根据定义,散列码会发生冲突。将它们添加在一起无助于此。

您应该使图形的边缘支持hashCode和equals,并且只需将边缘放在哈希集中即可。

class Edge { ... equals and hashCode ... }

HashSet<Edge> traversed = new HashSet<Edge>();
traversed.add(edge);
...
if(traversed.contains(edge)) ...

如果你正在为你的边编号,那么Integer已经有一个好的哈希码并且等于,所以使用它:

HashSet<Integer> traversed = new HashSet<Integer>();
if(traversed.contains(edgeNumber)) ...
traversed.add(3);

答案 2 :(得分:1)

只要您同时覆盖hashCode()equals(),就可以了。哈希码永远不会保证是唯一的。那就是说,你有点滥用Set。通过使用正确实施的hashCode()equals()方法存储类,contains()'等方法将具有完美的准确性。但是,这不是你在这里使用它的方式。听起来你几乎正在构建自己的数据结构/集合,你需要考虑这样做,就像'Hash'集合那样 - 使用HashMap来存储哈希的桶 - 哈希值作为key,然后是要比较的值的集合。这将允许您快速查看父地图是否具有您正在寻找的哈希。如果没有,你就完成了(假)。如果是,那么您需要确认其“桶”具有您正在寻找的特定值(true)。