亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java中equals和hashCode的作用是什么

發布時間:2021-07-19 09:46:10 來源:億速云 閱讀:168 作者:chen 欄目:大數據

這篇文章主要講解了“java中equals和hashCode的作用是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“java中equals和hashCode的作用是什么”吧!


 
equals

什么時候覆蓋equals方法我就不再說了,相信熟悉Java的讀者肯定都知道,我們著重聊一下如何書寫規范的equls方法。因為一個不規范的equals方法將會造成集合無法表現出預期的行為。

重寫equals方法需要保證equals滿足以下特性:

  • 自反性:對于任何非null的引用值x,必須滿足x.equals(x)返回true
  • 對稱性:對于任何非null的引用值x和y,當且僅當y.equals(x)返回true時,x.equals(y)必須返回true
  • 傳遞性:對于任何非null的引用值x、y、z,如果x.equals(y)返回true并且y.equals(z)返回true時,那么x.equals(z)也必須返回true
  • 一致性:對于任何非null的引用值x、y,只要equals涉及的字段信息沒有被修改,多次調用x.equals(y)要返回一樣的結果
  • 非空性:對于任何非null的引用值x,x.equals(null)必須返回false
 
自反性

該要求說明對象必須等于自身,如果違背這一條你會發下集合的contains方法無法告訴你正確的結果。

 
對稱性

對稱性要求兩個對象對于它們是否相等要保持一致,下面這段代碼違反了對稱性

public class IgnoreCaseString {
   private final String s;
   public IgnoreCaseString(String s) {        this.s = s;    }
   @Override    public boolean equals(Object obj) {        if (obj instanceof IgnoreCaseString) {            return s.equalsIgnoreCase(((IgnoreCaseString) obj).s);        }        if (obj instanceof String) {            return s.equalsIgnoreCase((String) obj);        }        return false;    }
   public static void main(String[] args) {        IgnoreCaseString ignoreCaseString = new IgnoreCaseString("Phone");        String string = "phone";        System.out.println(ignoreCaseString.equals(string));        System.out.println(string.equals(ignoreCaseString));        System.out.println("------------------------------");        List<String> list = new ArrayList<>();        list.add(string);        System.out.println(list.contains(ignoreCaseString));    }}
 
 
傳遞性

這種情況通常發生在具有父子關系的對象中,子類增加的信息會影響到equals的比較結果。解決這種問題通常有兩種方式,一種是通過getClass()的方式(具體的大家可以通過閱讀Effective Java這本書),還有一種是在我們擴展類的功能時盡量使用復合而并不是使用繼承,通過復合組件里面的域的比較也可以解決。

 
一致性

一致性要求如果兩個對象相等,那么他們就必須保持相等,除非它們中有對象被修改了。

 
非空性

非空性要求所有的對象不等于null

 
如何寫好equals
  1. 如果比較操作昂貴,可以優先使用==操作符檢查是否是同一個對象引用
  2. 使用instanceOf操作符檢查參數是否為正確的類型(正確的類型通常是指equals方法所在的那個類,但有時也是該類實現的某個接口,比如Set、List等集合)
  3. 把參數轉換為正確的類型
  4. 對于該類中的每個關鍵字段,檢查參數中的字段是否與該對象中對應的字段相匹配,對于既不是float也不是double類型的基本類型域,可以使用==操作符進行比較,對于引用類型可以遞歸調用equals方法,對于float使用Float.compare方法,double使用Double.compare方法,數組域可以使用Arrays.equals方法。
  5. 最最重要的一步,當編寫完equals方法一定要進行單元測試,驗證equals方法是否滿足上述特性。
 
hashCode

在每個覆蓋了equals方法的類中,必須重寫hashCode方法。如果不這樣做,會導致該類無法與所有基于散列的集合一起正常運作。hashCode方法需要遵循以下規定:

  • 在程序執行期間,只要對象的equals方法比較操作用到的信息沒有被修改,那么對于同一個對象調用多次hashCode方法必須返回同一個整數。但是在一個應用程序的多次執行中,每次執行可以返回的整數可以不一致。
  • 如果兩個對象的根據equals方法比較結果是相等的,那么調用任意一個對象的hashCode方法都必須產生相同的結果
  • 如果兩個對象根據equals方法比較結果不想等,那么調用這兩個對象的hashCode方法可以產生相同或者不同的整數結果,但是盡量保證程序可以產出不同的整數因為這樣可以提高散列表的性能
 
如何寫好hashCode
  1. 把某個非零的常數值,比如說17保存在一個result的int類型變量中
  2. 對于對象中equals方法中涉及到的每一個域(f)計算散列碼
  3. 按照result = 31 * result + c(第二步計算的散列碼)合并到result中并返回
  4. 驗證自己的hashCode方法

使用非0初始值的原因是讓域初始值為0的那些域可以影響到散列值,如果使用0那么散列值不會再受這些域的影響,從而增加Hash沖突的可能性,從而降低了散列表的性能

31是一個奇素數,在Java中如果兩個比較大的數相乘則會發生移除,31并不算一個比較大的數,其次選用31的理由是可以用移位和減法來代替乘法,31 * i = (i << 5) - i,現在的VM都可以自動完成這種優化,因此可以獲得很好的性能提升

 
計算散列碼
  • 如果f是boolean類型,計算f? 1 :0
  • 如果f是byte、char、short或者int類型,計算(int)f
  • 如果是long類型,計算(int)(f ^ (f>>>32))
  • 如果是float類型,計算Float.floatToIntBits(f)
  • 如果是double類型,計算Double.doubleToLongBits(f),然后在將得到long結果計算散列值
  • 如果是一個引用類型,遞歸調用hashCode
  • 如果是是一個數組,調用Arryas.hashCode方法

如果一個類是不可變的并且計算散列碼的成本比較大,可以考慮把散列碼緩存在對象內部,而不是每次請求時都重新計算(這一點在Kafka中也有所應用)。

感謝各位的閱讀,以上就是“java中equals和hashCode的作用是什么”的內容了,經過本文的學習后,相信大家對java中equals和hashCode的作用是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

太和县| 武强县| 库车县| 樟树市| 岳西县| 承德市| 思南县| 聊城市| 肇州县| 桐梓县| 绩溪县| 水城县| 滦南县| 高邮市| 哈巴河县| 仙居县| 林芝县| 鹿泉市| 株洲县| 荥经县| 咸阳市| 康马县| 宝鸡市| 兴义市| 炎陵县| 枞阳县| 廊坊市| 甘谷县| 峨眉山市| 广丰县| 丰镇市| 兰州市| 宁乡县| 崇礼县| 湖南省| 三门县| 昌都县| 旌德县| 彭州市| 石台县| 尼木县|