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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java equals()和hashCode()

發(fā)布時間:2023/12/3 java 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java equals()和hashCode() 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

介紹:

Java Object類提供了方法的基本實現(xiàn)– hashCode()和equals()。 這些方法非常有用,尤其是在使用Collection框架時。 哈希表實現(xiàn)依賴于這些方法來存儲和檢索數(shù)據(jù)。

在本教程中,我們將學(xué)習(xí)hashCode()和equals()之間的協(xié)定(它們的默認(rèn)實現(xiàn))。 我們還將討論何時以及如何覆蓋這些方法。

默認(rèn)行為:

首先讓我們看一下這些方法的默認(rèn)實現(xiàn):

存在于Object類中的equals()方法只是比較對象引用:

public boolean equals(Object obj) {return (this == obj); }

因此,默認(rèn)情況下, obj1.equals(obj2)與obj1 == obj2相同。

equals()方法比較諸如String等的類的實際值,因為它們在相應(yīng)的類中被覆蓋。

JDK中hashCode()方法的簽名為:

public native int hashCode();

在這里, native關(guān)鍵字表示該方法是使用JNI (Java本機(jī)接口)以本機(jī)代碼實現(xiàn)的。

hashCode()方法返回一個int類型。 默認(rèn)情況下,返回值表示對象存儲器地址。

實施原則:

在覆蓋equals()和hashCode()方法之前,我們先來看一下準(zhǔn)則:

1. equals(): ? 我們對equals()方法的實現(xiàn)必須是:

  • 反身:對于任何參考值obj , obj.equals(obj)應(yīng)該返回true
  • 對稱:對于參考值obj1和obj2 ,如果obj1.equals(obj2)為true,則obj2.equals(obj2)也應(yīng)返回true
  • 傳遞性:對于值OBJ1參考,OBJ 2和 OBJ 3,如果obj1.equals(OBJ 2) 真實 ,obj2.equals(OBJ 3)為真 ,那么obj1.equals(OBJ 3)也應(yīng)該返回true
  • 一致:只要我們沒有更改實現(xiàn), equals()方法的多次調(diào)用必須始終返回相同的值

2. hashCode():實現(xiàn)hashCode()時,必須考慮以下幾點(diǎn):

  • 在一次執(zhí)行中, hashCode()的多次調(diào)用必須返回相同的值,前提是我們不更改equals()實現(xiàn)中的屬性
  • 相等的對象必須返回相同的hashCode()值
  • 兩個或更多不相等的對象可以具有相同的hashCode()值

盡管在覆蓋這些方法時要牢記上述所有原則,但是其中有一個流行的規(guī)則:

對于兩個對象obj1和obj2 ,

  • 如果obj1.equals(obj2),則obj1.hashCode()= obj2.hashCode()必須為true
  • 但是,如果obj1.hashCode()== obj2.hashCode() ,則obj1.equals(obj2)可以返回true或false,即obj1和obj2可能相等或不相等

這通常被稱為equals()和hashCode()契約。

為什么覆蓋

hashCode()和equals()方法在基于哈希表的實現(xiàn)中存儲和檢索元素方面起著重要作用。 hashCode()確定給定項映射到的存儲桶。 在存儲桶中, equals()方法用于查找給定的條目。

假設(shè)我們有一個Employee類:

public class Employee {private int id;private String name;//constructors, getters, setters, toString implementations}

還有一個存儲Employee作為鍵的HashMap :

Map<Employee, Integer> map = new HashMap<>();map.put(new Employee(1, "Sam"), 1); map.put(new Employee(2, "Sierra"), 2);

現(xiàn)在我們已經(jīng)插入了兩個條目,讓我們嘗試一個containsKey()檢查:

boolean containsSam = map.containsKey(new Employee(1, "Sam")); //false

盡管我們有Sam的條目,但是containsKey()返回false 。 這是因為我們尚未覆蓋equals()和hashCode()方法。 默認(rèn)情況下, equals()只會進(jìn)行基于引用的比較。

覆蓋

根據(jù)Javadocs:

當(dāng)我們覆蓋equals()方法時,我們還必須覆蓋hashCode()方法。

這將有助于避免違反equals-hashCode合同。

請注意,如果我們違反合同,編譯器不會抱怨,但是當(dāng)我們將此類對象作為鍵存儲在HashMap中時,最終可能會遇到意外行為。

我們可以使用IDE的功能快速覆蓋這些方法。 使用Eclipse時,我們可以轉(zhuǎn)到Source-> Generate hashCode()和equals()。 讓我們看看為Employee類生成的實現(xiàn):

public class Employee {...@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + id;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Employee other = (Employee) obj;if (id != other.id)return false;if (name == null) {if (other.name != null)return false;} else if(!name.equals(other.name))return false;return true;} }

顯然,相同的字段已用于實現(xiàn)equals()和hashCode()方法,以與合同保持一致。

最佳做法:

使用equals()和hashCode()時應(yīng)遵循的一些最佳實踐包括:

  • 實現(xiàn)hashCode()以在各個存儲桶之間平均分配項目。 這樣做的目的是最大程度地減少碰撞次數(shù),從而獲得良好的性能
  • 對于equals()和hashCode()實現(xiàn),我們應(yīng)該使用相同的字段
  • 在HashMap中將不可變對象作為鍵,因為它們支持緩存哈希碼值
  • 使用ORM工具時,請始終使用getter代替hashCode()和equals()方法定義中的字段。 那是因為有些字段可能是延遲加載的

結(jié)論:

在本教程中,我們首先研究了equals()和hashCode()方法的默認(rèn)實現(xiàn)。 稍后,我們討論了何時以及如何覆蓋這些方法。

成為第一個發(fā)表評論的人。

翻譯自: https://www.javacodegeeks.com/2019/05/java-equals-hashcode.html

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。