java - Eclipse生成的hashCode函数好用吗?

标签 java eclipse hash hashmap hashtable

Eclipse 源菜单有一个“生成 hashCode/equals 方法”,它可以生成如下所示的函数。

String name; 
@Override
public int hashCode()
{
    final int prime = 31;
    int result = 1;
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    return result;
}

@Override
public boolean equals(Object obj)
{
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    CompanyRole other = (CompanyRole) obj;
    if (name == null)
    {
        if (other.name != null)
            return false;
    } else if (!name.equals(other.name))
        return false;
    return true;
}

如果我在生成 hashCode()equals() 时选择多个字段,Eclipse 使用上面显示的相同模式。

我不是哈希函数方面的专家,我想知道生成的哈希函数有多“好”?什么情况下它会发生故障并导致过多的碰撞?

最佳答案

java.util.ArrayList中可以看到hashCode函数的实现为

public int hashCode() {
    int hashCode = 1;
    Iterator<E> i = iterator();
    while (i.hasNext()) {
        E obj = i.next();
        hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
    }
    return hashCode;
}

这是一个这样的示例,您的 Eclipse 生成的代码遵循类似的实现方式。但是如果你觉得你必须自己实现你的 hashCode,那么 Joshua Bloch 在他的名著 Effective Java 中给出了一些很好的指导。 .我将发布该书第 9 项中的重要观点。那些是,

  1. Store some constant nonzero value, say, 17, in an int variable called result.
  2. For each significant field f in your object (each field taken into account by the equals method, that is), do the following:

    a. Compute an int hash code c for the field:

    i. If the field is a boolean, compute (f ? 1 : 0).

    ii. If the field is a byte, char, short, or int, compute (int) f.

    iii. If the field is a long, compute (int) (f ^ (f >>> 32)).

    iv. If the field is a float, compute Float.floatToIntBits(f).

    v. If the field is a double, compute Double.doubleToLongBits(f), and then hash the resulting long as in step 2.a.iii.

    vi. If the field is an object reference and this class’s equals method compares the field by recursively invoking equals, recursively invoke hashCode on the field. If a more complex comparison is required, compute a “canonical representation” for this field and invoke hashCode on the canonical representation. If the value of the field is null, return 0 (or some other constant, but 0 is traditional)

    vii. If the field is an array, treat it as if each element were a separate field. That is, compute a hash code for each significant element by applying these rules recursively, and combine these values per step 2.b. If every element in an array field is significant, you can use one of the Arrays.hashCode methods added in release 1.5.

    b. Combine the hash code c computed in step 2.a into result as follows:

       result = 31 * result + c;
    
  3. Return result.

  4. When you are finished writing the hashCode method, ask yourself whether equal instances have equal hash codes. Write unit tests to verify your intuition! If equal instances have unequal hash codes, figure out why and fix the problem.

Java 语言设计者和 Eclipse 似乎遵循我想的类似准则。快乐编码。干杯。

关于java - Eclipse生成的hashCode函数好用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11795104/

相关文章:

java - 包装外观模式

java - maven 中缺少子依赖项的解决方法

eclipse - Gradle多项目任务执行行为

arrays - 按数组中元素的数量对数组哈希中的键进行排序

来自远程的特定哈希的 git 存档

ruby-on-rails - ruby 将新的键值对添加到嵌套哈希

java - 如何编辑 native Java 类

java - myClass$1.class 类的 Java 类文件有什么意义?

java - 使用 Eclipse Luna 创建 Java、XML 应用程序

Java计算器