hashcode 以及equals 方法

2021-09-26 06:35:07 字數 3497 閱讀 7713

先從簡單的開始

鋪墊一下:

string str1="11";

string str2="11";

string str3=new string("111");

string str4=new string("111");

system.out.println("兩個string型別== 和equals方法 底層都重寫了equals方法");

system.out.println(str1==str2);

system.out.println(str1.equals(str2));

system.out.println("兩個strig物件也是 ==(比較的位址) 和equals方法(比較的內容) 重寫(equals)");

system.out.println(str3==str4);

system.out.println(str3.equals(str4));

//基本資料型別和所對應的包裝類 的道理都是相同的 也都重寫了equals方法

這個面試會有考到,而且跟jvm有些關係 具體先不展開了

這是結果

兩個string型別== 和equals方法  底層都重寫了equals方法

str1==str2:true

str1.equals(str2):true

兩個strig物件也是 ==(比較的位址) 和equals方法(比較的內容) 重寫(equals)

str3==str4:false

str3.equals(str4):true

可以看到 基本資料型別、string型別 == 和equals 都是相等的

但是類物件(包括包裝類、string類)中==是比較的是位址值 ,而equals中比較的是類中的內容(但是除(包裝類和string類)之外的要重寫equals()方法才行)至於為什麼???下面講

2、進一步深入,如果進一步深入肯定使用hash表,這個面試肯定也會涉及到的

具體的公式是這樣的

兩個物件的equals相等 則兩個物件的hashcode值一定相等

兩個物件的equals不想等,則連個物件的hashcode值一定不相等

兩個物件的hashcode相等 則兩個物件equals不一定相等

兩個物件的hashcode不相等 則兩個物件的equals一定不相等

還有 我記得有乙個這樣的原則 如果在hashset、hashmap等hash表中儲存key為物件的時候,

一定要重寫物件的hashcode方法和equals方法。

但是 上述的公式和原則是為什麼呢???????

先來看乙個儲存hashset中的小demo把

物件中先不重寫hashcode方法和equals

private int age;

private string name;

public student(int age, string name)

@override

public string tostring()

public static void main(string args) }}

結果:false

false

student [age=12, name=張三]

student [age=12, name=張三]

student [age=13, name=李四]`

小知識點:

*s1跟s2的內容相等但是 兩個物件hashcode值和equals 均為false

s1.hashcode() 如果s物件沒有重寫hashcode方法

* 底層呼叫的是public native int hashcode(); native暫時認為位址吧new兩個物件 位址肯定不相等

下面有個小問題:這裡揭示一下

為什麼 除(包裝類和string類)之外的要重寫equals()方法,equals才是比較的是內容

如果沒有重寫equals方法呼叫的是==:如下

* s1.equals(s2) 如果s物件沒有重寫equals方法底層呼叫的方法:

* public boolean equals(object obj)

還有:包裝類和string類底層都是已經重寫了equals方法的

我們應該都知道new兩個物件 本來就是不一樣的呀。s1本來就是不等於s2的呀(雖然內容一樣)

對,這是沒錯的

但這裡注意如果我們是使用hash表儲存資料,我們會約定儲存時s1一定要等於s2,這是為了進行去重操作。

但是為什麼物件作為key的時候,一定要重寫hashcode方法和equal方法??如果我只寫乙個呢????

下面:只重寫equals 不重寫hashcode

@override

public boolean equals(object obj) else if (!name.equals(other.name))

return false;

return true;

} 執行結果:

student [age=12, name=張三]

student [age=12, name=張三]

student [age=13, name=李四]

只重寫equals 不重寫hashcode

@override

public int hashcode()

結果:student [age=12, name=張三]

student [age=12, name=張三]

student [age=13, name=李四]

可以看出都是不行的 我們要的結果中只有乙個名字為張三 年齡12

如果把hashcode和equals方法同時寫上後:

student [age=12, name=張三] student [age=13, name=李四]

所以要同時重寫物件的equals方法和hashcode方法,才能得到存入hash表中沒有重複的元素

還沒完————————》

可以看一下hashmap中新增方法(hashset底層也是hashmap)

final v putval(int hash, k key, v value, boolean onlyifabsent,

boolean evict)

這裡hashset中存入的e e元素就是相等於hashmap中key值。

還有其中的present

private static final object present = new object();

我理解就是乙個常量物件吧。

總結一點:

上述set儲存物件的時候所需要的條件,相當與在hashmap中儲存時 key充當物件同樣所需要滿足的條件。

game over

本人理解大概這麼多。

JAVA基礎 equal和hashcode的區別

面試時被問到了equal和hashcode的區別,在這裡總結一下 equals 是根類obeject 中的方法。源 如下 public boolean equals object obj 可見預設的 equals 方法,直接呼叫 比較物件位址。不同的子類,可以重寫此方法,進行兩個物件的 equals...

HashCode和equal方法的區別和聯絡

hashcode 和 equal方法過載 1 為什麼要過載equal方法?答案 因為object的equal方法預設是兩個物件的引用的比較,意思就是指向同一記憶體,位址則相等,否則不相等 如果你現在需要利用物件裡面的值來判斷是否相等,則過載equal方法。2 為什麼過載hashcode方法?答案 一...

帶我重新認識HashCode和equals

介紹一下equals equals 比較兩個物件是不是相同,問題來了,equals比較的是位址,引用,這也是最準確的方法。介紹一下hashcode hashcode 返回的是當前物件的實體地址轉換成的乙個int型別資料,看清楚這裡是轉換,不是等於。所以不能唯一確定物件是不是同乙個物件。他們之間的關係...