What is the hashCode for a custom class having just two int properties?(只有两个int属性的定制类的hashCode是什么?)
问题描述
在Java中,我有一个用int坐标表示点的类
public class Point {
int x = -1;
int y = -1;
public Point (int xNew, int yNew) {
x = xNew; y = yNew;
}
public boolean equals (Object o) {
// no need for (o instanceof Point) by design
return x == ((Point)o).x && y == ((Point)o).y;
}
}
我使用Point
类的对象作为HashMap
中的键,并作为HashSet
中的元素。
hashCode
函数的最佳候选者是什么?我会将其加倍,这样左边的部分是x,右边的部分是y,例如:
x = 4, y = 12
,则hashCode
返回4.12
。但通过实现,它不能是Double,只能是int。
这不是一个选项:
public int hashCode() {
// no need to check for exception parseInt since x and y are valid by design
return Integer.parseInt(Integer.toString(x) + Integer.toString(y));
}
因为值x
和y
可能太长,所以它们加在一起不会被转换。
推荐答案
您不能更改hashCode
的类型,也不应该更改。
我只会这样做:
public int hashCode() {
return x * 31 + y;
}
请注意,这意味着在大多数情况下(a,b)不同于(b,a)(不同于加法或异或运算)。如果您在实际生活中经常使用"已切换"值的键,这可能会很有用。
它不是唯一的-但散列代码不一定是唯一的。对于相同的值,只是必须相同(为了正确),而对于不相等的值,它们"通常"是不同的,并具有合理的分布。
总的来说,我通常遵循Josh Bloch在《Efficient Java:
》中建议的模式:public int hashCode() {
int hash = 17;
hash = hash * 31 + field1Hash;
hash = hash * 31 + field2Hash;
hash = hash * 31 + field3Hash;
hash = hash * 31 + field4Hash;
...
return hash;
}
其中field1Hash
将是引用类型字段的散列代码(或0表示空引用),int
本身是整数值的散列代码,long
是从64位到32位的某种散列,等等。
编辑:我记不清为什么31和17在一起工作得很好的细节。它们都是素数这一事实可能有用--但据我所知,这种散列背后的数学原理通常是合理的(尽管不如预先知道可能值分布的散列好),要么很难理解,要么就不能很好地理解。我知道乘以31比较便宜(左移5并减去原值)...
这篇关于只有两个int属性的定制类的hashCode是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:只有两个int属性的定制类的hashCode是什么?
基础教程推荐
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01