我正在学习Java中的hashcode()方法。我正在看教程
并且看到hashcode()主要用于HashMap,HashTable和HashSet中。
这就是我所了解的,如果要插入一个对象作为键,则必须重写hashcode()。
其他它将无法查找密钥。
我做了一个小例子,无需覆盖hashCode就可以实现。
那么hashCode()的确切用途是什么?

见下面的代码

package hashcode;

public class Bucket {

    private int number;

    public void setNumber(int number) {
        this.number = number;
    }

    public int getNumber() {
        return number;
    }

    @Override
    public String toString() {
        return "" + number;
    }

}


package hashcode;

import java.util.Hashtable;

public class MainHashcodeExample {

    public static void main(String[] args) {

        Hashtable<Bucket, String> map = new Hashtable<>();
        Bucket bucket = new Bucket();
        bucket.setNumber(100);
        map.put(bucket, "A");

        System.out.println(map.get(bucket));

    }
}

最佳答案

您正在使用与Bucket完全相同的引用,因此使用.hashCode().equals()的默认实现(分别为System.identityHashCode()和引用相等)。

现在尝试:

Set<Bucket> set = new HashSet<>();

// Create two buckets b1, b2 with the same number

set.add(b1); set.add(b2);


该集合的大小为2。如果b1b2相等(不是),则该集合的大小为1。

现在,让我们假设您实现了.equals()而不是.hashCode()

// no hashCode(), but...

@Override
// simplified
public boolean equals(@Nullable final Object obj)
{
    // instanceOf works with null, so this works
    if (!(obj instanceOf Bucket))
        return false;
    return ((Bucket) obj).number == number;
}


然后运行上面的代码...集合仍将具有大小2。为什么?因为b1b2是不同的引用,并且Object.hashCode()将(很可能)为两者返回不同的结果。

因此,您需要同时覆盖.equals().hashCode()才能正确使用。有关更多详细信息,请参见javadoc of Object,并详细说明了两者的合同。

还请注意,.hashCode()没有“加密值”。这是一个完全合法(尽管没有用)的实现:

@Override
public int hashCode()
{
    return 42;
}

关于java - 哈希码使用未在代码中显示,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26649111/

10-14 08:45