日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

hashCode之二--Java:重写equals()和hashCode()

發布時間:2023/12/2 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hashCode之二--Java:重写equals()和hashCode() 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
以下內容總結自《Effective Java》。 1.何時需要重寫equals() 當一個類有自己特有的“邏輯相等”概念(不同于對象身份的概念)。 2.設計equals() [1]使用instanceof操作符檢查“實參是否為正確的類型”。 [2]對于類中的每一個“關鍵域”,檢查實參中的域與當前對象中對應的域值。 [2.1]對于非float和double類型的原語類型域,使用==比較; [2.2]對于對象引用域,遞歸調用equals方法; [2.3]對于float域,使用Float.floatToIntBits(afloat)轉換為int,再使用==比較; [2.4]對于double域,使用Double.doubleToLongBits(adouble) 轉換為int,再使用==比較; [2.5]對于數組域,調用Arrays.equals方法。 3.當改寫equals()的時候,總是要改寫hashCode() 根據一個類的equals方法(改寫后),兩個截然不同的實例有可能在邏輯上是相等的,但是,根據Object.hashCode方法,它們僅僅是兩個對象。因此,違反了“相等的對象必須具有相等的散列碼”。 4.設計hashCode() [1]把某個非零常數值,例如17,保存在int變量result中; [2]對于對象中每一個關鍵域f(指equals方法中考慮的每一個域): [2.1]boolean型,計算(f ? 0 : 1); [2.2]byte,char,short型,計算(int); [2.3]long型,計算(int) (f ^ (f>>>32)); [2.4]float型,計算Float.floatToIntBits(afloat); [2.5]double型,計算Double.doubleToLongBits(adouble)得到一個long,再執行[2.3]; [2.6]對象引用,遞歸調用它的hashCode方法; [2.7]數組域,對其中每個元素調用它的hashCode方法。Arrays.hashCode(...)只會計算一維數組元素的hashCOde,如果是多維數組,那么需要遞歸進行hashCode的計算,那么就需要使用Arrays.deepHashCode(Object[])方法。 [3]將上面計算得到的散列碼保存到int變量c,然后執行 result=37*result+c; [4]返回result。 為什么每次需要使用乘法去操作result?  主要是為了使散列值依賴于域的順序,還是上面的那個例子,Test t = new Test(1, 0)跟Test t2 = new Test(0, 1), t和t2的最終hashCode返回值是不一樣的。 為什么是31? 31是個神奇的數字,因為任何數n * 31就可以被JVM優化為 (n << 5) -n,移位和減法的操作效率要比乘法的操作效率高的多。 我們應該先了解java判斷兩個對象是否相等的規則。
在java的集合中,判斷兩個對象是否相等的規則是:?
首先,判斷兩個對象的hashCode是否相等
如果不相等,認為兩個對象也不相等
如果相等,則判斷兩個對象用equals運算是否相等?
如果不相等,認為兩個對象也不相等?
如果相等,認為兩個對象相等
我們在equals方法中需要向下轉型,效率很低,所以先判斷hashCode方法可以提高效率
如何重寫hashCode方法呢? 5.示例 下面的這個類遵循上面的設計原則,重寫了類的equals()和hashCode()。 package com.zj.unit; import java.util.Arrays; public class Unit { private short ashort; private char achar; private byte abyte; private boolean abool; private long along; private float afloat; private double adouble; private Unit aObject; private int[] ints; private Unit[] units; public boolean equals(Object o) { if (!(o instanceof Unit)) return false; Unit unit = (Unit) o; return unit.ashort == ashort && unit.achar == achar && unit.abyte == abyte && unit.abool == abool && unit.along == along && Float.floatToIntBits(unit.afloat) == Float .floatToIntBits(afloat) && Double.doubleToLongBits(unit.adouble) == Double .doubleToLongBits(adouble) && unit.aObject.equals(aObject) && equalsInts(unit.ints) && equalsUnits(unit.units); } private boolean equalsInts(int[] aints) { return Arrays.equals(ints, aints); } private boolean equalsUnits(Unit[] aUnits) { return Arrays.equals(units, aUnits); } public int hashCode() { int result = 17; result = 37 * result + (int) ashort; result = 37 * result + (int) achar; result = 37 * result + (int) abyte; result = 37 * result + (abool ? 0 : 1); result = 37 * result + (int) (along ^ (along >>> 32)); result = 37 * result + Float.floatToIntBits(afloat); long tolong = Double.doubleToLongBits(adouble); result = 37 * result + (int) (tolong ^ (tolong >>> 32)); result = 37 * result + aObject.hashCode(); result = 37 * result + intsHashCode(ints); result = 37 * result + unitsHashCode(units); return result; } private int intsHashCode(int[] aints) { int result = 17; for (int i = 0; i < aints.length; i++) result = 37 * result + aints[i]; return result; } private int unitsHashCode(Unit[] aUnits) { int result = 17; for (int i = 0; i < aUnits.length; i++) result = 37 * result + aUnits[i].hashCode(); return result; } }

轉載于:https://www.cnblogs.com/duanxz/p/3890046.html

總結

以上是生活随笔為你收集整理的hashCode之二--Java:重写equals()和hashCode()的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。