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

歡迎訪問 生活随笔!

生活随笔

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

java

Java基础之equals和==的区别深入解析

發布時間:2024/2/28 java 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java基础之equals和==的区别深入解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java基礎之equals和==的區別深入解析


以下是本文目錄大綱

  • equals 和 == 的區別
  • equals 的重寫
  • 復寫hashCode方法,有31這個數字的作用

  • 1. equals 和 == 的區別

    // object類下的equals public boolean equals(Object obj) {return (this == obj);} //String類下的euqals public boolean equals(Object anObject) {if (this == anObject) {return true;}if (anObject instanceof String) {String anotherString = (String)anObject;int n = value.length;if (n == anotherString.value.length) {char v1[] = value;char v2[] = anotherString.value;int i = 0;while (n-- != 0) {if (v1[i] != v2[i])return false;i++;}return true;}}return false;}
    • 首先,我們知道 == 既可以比較基本類型也可以比較引用類型。對于基本類型就是比較值,對于引用類型就是比較內存地址。
    • 通過equals源碼可以看出,equals是java.lang.Object類里面的方法,如果該方法沒有被重寫過默認也是==,String類的equals方法是被重寫過的,先比length是否相同,相同再比較value是否相同,且String類在日常開發中用的比較多,久而久之,形成了equals是比較值的錯誤觀點
    接下來我們再看個代碼加深理解
    public class stringTest {public static void main(String[] args) {String s1 = new String("abc");String s2 = new String("abc");System.out.println(s1==s2);System.out.println(s1.equals(s2));System.out.println("======================");Set<String> set = new HashSet<>();set.add(s1);set.add(s2);System.out.println(s1.hashCode()+"\t"+s2.hashCode());System.out.println(set.size());System.out.println("============");Person p1 = new Person("abc");Person p2 = new Person("abc");System.out.println(p1 == p2);System.out.println(p1.equals(p2));Set<Person> set2 = new HashSet<Person>();set2.add(p1);set2.add(p2);System.out.println(p1.hashCode()+"\t"+p2.hashCode());System.out.println(set2.size());}}
    結果:
    false true ====================== 96354 96354 1 ============ false false 1163157884 1956725890 2
    解釋:
    • s1,s2是引用類型且是String類型(即equals方法有重寫)
    • s1==s2 比較的是內存地址,所以 false
    • s1.equals(s2) 的equals重寫過,先比較length,再比較value,所以true
    • 復寫后s1,s2是同一個對象,所以hashCore值相同
    • 即能解釋 set.size() = 1

    同理可以解釋p1和p2

    • p1,p2為引用類型且是Person類型(即equals沒有重寫)
    • p1==p2 比較的是內存地址,所以 false
    • s1.equals(s2) 的equals沒有重寫過等價于==,所以false
    • p1,p2是兩個對象,所以hashCore值不相同
    • 即能解釋 set2.size() = 2

    畫圖:


    畫圖如上,自我理解,有錯誤請指出。


    總結
  • == 既可以比較基本類型也可以比較引用類型。對于基本類型就是比較值,對于引用類型就是比較內存地址

  • Equals的話,它是屬于java.lang.Object類里面的方法,如果該方法沒有被重寫過默認也是==;我們可以看到String類的equals方法是被重寫過的,而且String類在日常開發中用的比較多,久而久之,形成了equals是比較值的錯誤觀點。

  • 具體要看這有沒有重寫Object的hashCode方法和equals方法來判斷。


  • 2. equals 的重寫


    可以看出,重寫equals,重寫就要同時重寫equals()和hashCode()。

    當一個類有自己特有的“邏輯相等”概念,當改寫equals()的時候,總是要改寫hashCode(),根據一個類的equals方法(改寫后),兩個截然不同的實例有可能在邏輯上是相等的,但是,根據Object.hashCode方法,它們僅僅是兩個對象。以Person為例,兩個人都叫張三,但不是同一個人(equals),需要看的不是名字,而是身份證號碼(hashCode)

    因此,違反了“相等的對象必須具有相等的散列碼”。

    結論:復寫equals方法的時候一般都需要同時復寫hashCode方法。


    3. 復寫hashCode方法,31這個數字的作用

    源碼:

    public int hashCode() {int h = hash;if (h == 0 && value.length > 0) {char val[] = value;for (int i = 0; i < value.length; i++) {h = 31 * h + val[i];}hash = h;}return h;}

    計算機的乘法涉及到移位計算。當一個數乘以2時,就直接拿該數左移一位即可!選擇31原因是因為31是一個素數。(素數:質數又稱素數,在一個大于1的自然數中,除了1和此整數自身外,沒法被其他自然數整除的數)

    在存儲數據計算hash地址的時候,我們希望盡量減少有同樣的hash地址,所謂“沖突”。

    因為任何數n * 31就可以被JVM優化為 (n << 5) -n,移位和減法的操作效率要比乘法的操作效率高的多,對左移虛擬機里面都有做相關優化,并且31只占用5bits。

    總結

    以上是生活随笔為你收集整理的Java基础之equals和==的区别深入解析的全部內容,希望文章能夠幫你解決所遇到的問題。

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