先從簡單的開始
鋪墊一下:
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型別資料,看清楚這裡是轉換,不是等於。所以不能唯一確定物件是不是同乙個物件。他們之間的關係...