本文介紹了只有兩個int屬性的定制類的hashCode是什么?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!
問題描述
在Java中,我有一個用int坐標(biāo)表示點(diǎn)的類
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
函數(shù)的最佳候選者是什么?我會將其加倍,這樣左邊的部分是x,右邊的部分是y,例如:
x = 4, y = 12
,則hashCode
返回4.12
。但通過實(shí)現(xiàn),它不能是Double,只能是int。
這不是一個選項(xiàng):
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));
}
因?yàn)橹?code>x和y
可能太長,所以它們加在一起不會被轉(zhuǎn)換。
推薦答案
您不能更改hashCode
的類型,也不應(yīng)該更改。
我只會這樣做:
public int hashCode() {
return x * 31 + y;
}
請注意,這意味著在大多數(shù)情況下(a,b)不同于(b,a)(不同于加法或異或運(yùn)算)。如果您在實(shí)際生活中經(jīng)常使用”已切換”值的鍵,這可能會很有用。
它不是唯一的-但散列代碼不一定是唯一的。對于相同的值,只是必須相同(為了正確),而對于不相等的值,它們”通常”是不同的,并具有合理的分布。
總的來說,我通常遵循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
本身是整數(shù)值的散列代碼,long
是從64位到32位的某種散列,等等。
編輯:我記不清為什么31和17在一起工作得很好的細(xì)節(jié)。它們都是素數(shù)這一事實(shí)可能有用–但據(jù)我所知,這種散列背后的數(shù)學(xué)原理通常是合理的(盡管不如預(yù)先知道可能值分布的散列好),要么很難理解,要么就不能很好地理解。我知道乘以31比較便宜(左移5并減去原值)…
這篇關(guān)于只有兩個int屬性的定制類的hashCode是什么?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,