错误理解java中的哈希函数和包含HashSet

时间:2017-11-03 22:06:19

标签: java

在Java中使用哈希和HashSet时,我有些疑惑。

我们知道应该满足的假设:

if elements are equals then also their hashes are equals
换句话说,

a.equals(b) ---> a.hashCode() == b.hashCode()   

但是,我们不能这样说

a.hashCode() == b.hashCode() --->  a.equals(b)   

问题在于我读了包含HashSet计算哈希h的内容,然后只在桶中搜索哈希h的元素。它没有为equals的存储分元调用h - 它只会hashCode。这意味着我们contains可以返回错误的答案,如果元素具有等于哈希值,但equals返回false(正如我上面提到的那样可能)。

2 个答案:

答案 0 :(得分:1)

虽然确实如此

a.hashCode() == b.hashCode() doesn't mean that a.equals(b)

当调用Java HashSet中包含Method时,将调用后备HashMap的containsKey方法。此方法检查该Object的Node是否为null,getNode函数还检查该键是否等于该对象

final Node<K,V> getNode(int hash, Object key) {
    Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
    if ((tab = table) != null && (n = tab.length) > 0 &&
        (first = tab[(n - 1) & hash]) != null) {
        if (first.hash == hash && // always check first node
            ((k = first.key) == key || (key != null && key.equals(k))))
            return first;
        if ((e = first.next) != null) {
            if (first instanceof TreeNode)
                return ((TreeNode<K,V>)first).getTreeNode(hash, key);
            do {
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k))))
                    return e;
            } while ((e = e.next) != null);
        }
    }
    return null;
}

答案 1 :(得分:1)

首先,您应该了解hashmap在java中的工作原理:

  1. java中的HashMap将key和value对象存储在bucket中,作为Entry类的对象,它实现嵌套接口Map.Entry。

  2. 当put()方法用于存储(Key,Value)对时,HashMap实现调用Key对象上的hashcode来计算用于查找将存储Entry对象的存储桶的哈希。当get()方法用于检索值时,再次使用key对象来计算哈希值,然后使用该哈希值查找存储该特定密钥的存储桶。

  3. HashMap密钥对象用于比较,也使用equals()方法Map知道如何处理哈希冲突(哈希冲突意味着多个密钥具有相同的哈希值,因此分配给同一个桶。在这种情况下,对象存储在链表中

  4. hashCode方法有助于找到存储该密钥的存储桶,equals方法有助于找到正确的密钥,因为在一个存储桶中可能存在多个键值对。

  5. 所以现在打电话给你的问题

    我。如果元素等于,那么它们的哈希值也是等于 II。 a.equals(b)---&gt; a.hashCode()== b.hashCode() III。 a.hashCode()== b.hashCode()---&gt; a.equals(b)中

      

    Blockquote并不总是如此,两个不等对象拥有相同的哈希码是完全合法的。它被HashMap用作“第一遍过滤器”,以便地图可以快速找到具有指定键的可能条目。如果两个不相等的对象不能具有相同的哈希码,则会将您限制为2 ^ 32个可能的对象。

    现在来到HashSet

      

    Blockquote Set是一组唯一对象,Java定义唯一性HashSet中的两个对象不相等