java - 为自定义类生成 hashCode()

标签 java hashcode

我有一个名为 Dish 的类,我在 ArrayList 中处理它 所以我必须重写默认的 hashCode() 方法。

@Override
public int hashCode() {
    int hash =7;
    hash = 3*hash + this.getId();
    hash = 3*hash + this.getQuantity();
    return hash;
}

当我拿到两道菜时,id=4quan=3id=5quan=0, hashCode() 两者相同;

((7*3)+4)*3+3 = 78
((7*3)+5)*3+0 = 78

我做错了什么?或者我选择的魔数(Magic Number) 7 和 3 是错误的?

如何正确重写 hashCode() 以便它生成唯一的哈希值?

PS:从我从谷歌和SO搜索到的内容来看,人们使用不同的数字但使用相同的方法。如果问题出在数字上,我如何明智地选择实际上不会增加​​乘法成本的数字,同时即使对于更多数量的属性也能很好地工作。

Say I had 7 int attributes and my second magic no. is 31, the final hash will be first magic no. * 27512614111 even if all my attributes are 0. So how do I do it without having my hashed value in billions so as keep my processor burden-free?

最佳答案

你可以使用这样的东西

public int hashCode() {
     int result = 17;
     result = 31 * result + getId();
     result = 31 * result + getQuantity();
     return result;
}

还有一件事,如果您的 id 对于每个对象都是唯一的,那么在计算哈希码时无需使用数量。

这是 Joshua bloch 摘自《Effective Java》的摘录,讲述如何实现 hashcode 方法

  1. 将一些常量非零值(例如 17)存储在名为 result 的 int 变量中。

  2. 对于对象中的每个重要字段 f(即 equals 方法考虑的每个字段),请执行以下操作:

    a.计算该字段的 int 哈希码 c:

    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.将步骤2.a中计算出的哈希码c组合成结果如下: 结果 = 31 * 结果 + c;

  3. 返回结果。

  4. 编写完 hashCode 方法后,问问自己相等的实例是否具有相等的哈希码。编写单元测试来验证您的直觉!如果相同的实例具有不相等的哈希码,请找出原因并解决问题。

来源:Joshua Bloch 的《Effective Java》

关于java - 为自定义类生成 hashCode(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36147943/

相关文章:

java - 从相对路径读取 XML - java.io.FileNotFoundException :(The system cannot find the path specified)

java - 如何解析 HTML 字符串以按父 div 拆分?

java - 为什么我的 HashSet 存储 2 个具有相同 hashCode 的相同对象?

hashcode - Objects.hash() 与 Objects.hashCode(),需要澄清

Java Map 哈希码

java - 如何导入 java 的 multimap?

java - 在 Java 二维数组中查找最小值和最大值

java - 如何创建一个使用数组来计算元音的程序?

java - 如何使用 equals() 和 hashCode() 实现近似几何相等

java - 以下情况的 hashCode() 方法 : two sets are equal when they have at least one element in common?