为自定义 class 生成 hashCode()
Generating hashCode() for a custom class
我有一个名为 Dish
的 class,我在 ArrayList
中处理它
所以我不得不覆盖默认的 hashCode()
方法。
@Override
public int hashCode() {
int hash =7;
hash = 3*hash + this.getId();
hash = 3*hash + this.getQuantity();
return hash;
}
当我得到 id=4
、quan=3
和 id=5
、quan=0
两个菜时,两者的 hashCode()
相同;
((7*3)+4)*3+3 = 78
((7*3)+5)*3+0 = 78
我做错了什么?还是我选的幻数7和3错了?
如何正确覆盖 hashCode()
以便它生成唯一的哈希值?
PS:从我从google和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?
这完全没问题。散列函数不应该是普遍唯一的 - 它只是给出一个快速提示,说明哪些元素 可能 相等,应该通过调用 equals().
从class的名字看数量好像就是菜的数量。因此,有很多次它可能为零。我会说,如果 getquantity() 为零,请在散列 fucntion.like this:
中使用变量 say x
@Override
public int hashCode() {
int hash =7;int x =0;
if(getQuantity==0)
{
x = getQuantity+getId();
}
else
{
x = getquantity;
}
hash = 3*hash + this.getId();
hash = 3*hash + x;
return hash;
}
我相信这应该可以减少 hash.since 的冲突 你拥有的 getId() 是唯一的 number.it 让 x 也成为唯一的数字。
你可以使用这样的东西
public int hashCode() {
int result = 17;
result = 31 * result + getId();
result = 31 * result + getQuantity();
return result;
}
还有一件事,如果您的 ID 对于每个对象都是唯一的,那么在计算哈希码时就不需要使用数量。
这是来自 Joshua bloch 的 Effective Java 的摘录,讲述了如何实现 hashcode 方法
在名为 result 的 int 变量中存储一些常量非零值,例如 17。
对于对象中的每个重要字段 f(即,equals 方法考虑的每个字段),执行以下操作:
一个。计算字段的 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;
Return 结果 .
写完 hashCode 方法后,问问自己相等的实例是否具有相等的哈希码。编写单元测试来验证您的直觉!如果相等的实例具有不相等的哈希码,找出原因并解决问题。
资料来源:Joshua Bloch
有效 Java
我有一个名为 Dish
的 class,我在 ArrayList
中处理它
所以我不得不覆盖默认的 hashCode()
方法。
@Override
public int hashCode() {
int hash =7;
hash = 3*hash + this.getId();
hash = 3*hash + this.getQuantity();
return hash;
}
当我得到 id=4
、quan=3
和 id=5
、quan=0
两个菜时,两者的 hashCode()
相同;
((7*3)+4)*3+3 = 78
((7*3)+5)*3+0 = 78
我做错了什么?还是我选的幻数7和3错了?
如何正确覆盖 hashCode()
以便它生成唯一的哈希值?
PS:从我从google和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?
这完全没问题。散列函数不应该是普遍唯一的 - 它只是给出一个快速提示,说明哪些元素 可能 相等,应该通过调用 equals().
从class的名字看数量好像就是菜的数量。因此,有很多次它可能为零。我会说,如果 getquantity() 为零,请在散列 fucntion.like this:
中使用变量 say x @Override
public int hashCode() {
int hash =7;int x =0;
if(getQuantity==0)
{
x = getQuantity+getId();
}
else
{
x = getquantity;
}
hash = 3*hash + this.getId();
hash = 3*hash + x;
return hash;
}
我相信这应该可以减少 hash.since 的冲突 你拥有的 getId() 是唯一的 number.it 让 x 也成为唯一的数字。
你可以使用这样的东西
public int hashCode() {
int result = 17;
result = 31 * result + getId();
result = 31 * result + getQuantity();
return result;
}
还有一件事,如果您的 ID 对于每个对象都是唯一的,那么在计算哈希码时就不需要使用数量。
这是来自 Joshua bloch 的 Effective Java 的摘录,讲述了如何实现 hashcode 方法
在名为 result 的 int 变量中存储一些常量非零值,例如 17。
对于对象中的每个重要字段 f(即,equals 方法考虑的每个字段),执行以下操作:
一个。计算字段的 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;
Return 结果 .
写完 hashCode 方法后,问问自己相等的实例是否具有相等的哈希码。编写单元测试来验证您的直觉!如果相等的实例具有不相等的哈希码,找出原因并解决问题。
资料来源:Joshua Bloch
有效 Java