欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
詳解重寫(xiě)equals()方法就必須重寫(xiě)hashCode()方法的原因

   從Object類(lèi)的hashCode()和equals()方法講起:   

      最近看了Object類(lèi)的源碼,對hashCode() 和equals()方法有了更深的認識。重寫(xiě)equals()方法就必須重寫(xiě)hashCode()方法的原因,從源頭Object類(lèi)講起就更好理解了。

先來(lái)看Object關(guān)于hashCode()和equals()的源碼:

    public native int hashCode();
  1. public boolean equals(Object obj) {
  2. return (this == obj);
  3. }
     光從代碼中我們可以知道,hashCode()方法是一個(gè)本地native方法,返回的是對象引用中存儲的對象的內存地址,而equals方法是利用==來(lái)比較的也是對象的內存地址。從上邊我們可以看出,hashCode方法和equals方法是一致的。還有最關(guān)鍵的一點(diǎn),我們來(lái)看Object類(lèi)中關(guān)于hashCode()方法的注釋?zhuān)?p>

  1. /**
  2. * Returns a hash code value for the object. This method is
  3. * supported for the benefit of hash tables such as those provided by
  4. * {@link java.util.HashMap}.
  5. * <p>
  6. * The general contract of {@code hashCode} is:
  7. * <ul>
  8. * <li>Whenever it is invoked on the same object more than once during
  9. * an execution of a Java application, the {@code hashCode} method
  10. * must consistently return the same integer, provided no information
  11. * used in {@code equals} comparisons on the object is modified.
  12. * This integer need not remain consistent from one execution of an
  13. * application to another execution of the same application.
  14. * <li>If two objects are equal according to the {@code equals(Object)}
  15. * method, then calling the {@code hashCode} method on each of
  16. * the two objects must produce the same integer result.
  17. * <li>It is <em>not</em> required that if two objects are unequal
  18. * according to the {@link java.lang.Object#equals(java.lang.Object)}
  19. * method, then calling the {@code hashCode} method on each of the
  20. * two objects must produce distinct integer results. However, the
  21. * programmer should be aware that producing distinct integer results
  22. * for unequal objects may improve the performance of hash tables.
  23. * </ul>
  24. * <p>
  25. * As much as is reasonably practical, the hashCode method defined by
  26. * class {@code Object} does return distinct integers for distinct
  27. * objects. (This is typically implemented by converting the internal
  28. * address of the object into an integer, but this implementation
  29. * technique is not required by the
  30. * Java? programming language.)
  31. *
  32. * @return a hash code value for this object.
  33. * @see java.lang.Object#equals(java.lang.Object)
  34. * @see java.lang.System#identityHashCode
  35. */
  36. public native int hashCode();
    簡(jiǎn)單的翻譯一下就是,hashCode方法一般的規定是:

  1. 1.在 Java 應用程序執行期間,在對同一對象多次調用 hashCode 方法時(shí),必須一致地返回相同的整數,前提是將對象進(jìn)行 equals 比較時(shí)所用的信息沒(méi)有被修改。從某一應用程序的一次執行到同一應用程序的另一次執行,該整數無(wú)需保持一致。
  2. 2.如果根據 equals(Object) 方法,兩個(gè)對象是相等的,那么對這兩個(gè)對象中的每個(gè)對象調用 hashCode 方法都必須生成相同的整數結果。
  3. 3.如果根據 equals(java.lang.Object) 方法,兩個(gè)對象不相等,那么對這兩個(gè)對象中的任一對象上調用 hashCode 方法不 要求一定生成不同的整數結果。但是,程序員應該意識到,為不相等的對象生成不同整數結果可以提高哈希表的性能。

     再簡(jiǎn)單的翻譯一下第二三點(diǎn)就是:hashCode()和equals()保持一致,如果equals方法返回true,那么兩個(gè)對象的hasCode()返回值必須一樣。如果equals方法返回false,hashcode可以不一樣,但是這樣不利于哈希表的性能,一般我們也不要這樣做。重寫(xiě)equals()方法就必須重寫(xiě)hashCode()方法的原因也就顯而易見(jiàn)了。

   假設兩個(gè)對象,重寫(xiě)了其equals方法,其相等條件是屬性相等,就返回true。如果不重寫(xiě)hashcode方法,其返回的依然是兩個(gè)對象的內存地址值,必然不相等。這就出現了equals方法相等,但是hashcode不相等的情況。這不符合hashcode的規則。下邊,會(huì )介紹在集合框架中,這種情況會(huì )導致的嚴重問(wèn)題。

    重寫(xiě)的作用:

        如果重寫(xiě)(用于需求,比如建立一個(gè)Person類(lèi),比較相等我只比較其屬性身份證相等就可不管其他屬性,這時(shí)候重寫(xiě))equals,就得重寫(xiě)hashCode,和其對象相等保持一致。如果不重寫(xiě),那么調用的Object中的方法一定保持一致。
       1.  重寫(xiě)equals()方法就必須重寫(xiě)hashCode()方法主要是針對HashSet和Map集合類(lèi)型。集合框架只能存入對象(對象的引用(基本類(lèi)型數據:自動(dòng)裝箱))。
        在向HashSet集合中存入一個(gè)元素時(shí),HashSet會(huì )調用該對象(存入對象)的hashCode()方法來(lái)得到該對象的hashCode()值,然后根據該hashCode值決定該對象在HashSet中存儲的位置。簡(jiǎn)單的說(shuō):HashSet集合判斷兩個(gè)元素相等的標準是:兩個(gè)對象通過(guò)equals()方法比較相等,并且兩個(gè)對象的HashCode()方法返回值也相等。如果兩個(gè)元素通過(guò)equals()方法比較返回true,但是它們的hashCode()方法返回值不同,HashSet會(huì )把它們存儲在不同的位置,依然可以添加成功。同樣:在Map集合中,例如其子類(lèi)Hashtable(jdk1.0錯誤的命名規范),HashMap,存儲的數據是<key,value>對,key,value都是對象,被封裝在Map.Entry,即:每個(gè)集合元素都是Map.Entry對象。在Map集合中,判斷key相等標準也是:兩個(gè)key通過(guò)equals()方法比較返回true,兩個(gè)key的hashCode的值也必須相等。判斷valude是否相等equal()相等即可。
      稍微提一句:(1)兩個(gè)對象,用==比較比較的是地址,需采用equals方法(可根據需求重寫(xiě))比較。
                              (2)重寫(xiě)equals()方法就重寫(xiě)hashCode()方法。
                               (3)一般相等的對象都規定有相同的hashCode。
                                hash:散列,Map關(guān)聯(lián)數組,字典
     2. 集合類(lèi)都重寫(xiě)了toString方法。String類(lèi)重寫(xiě)了equal和hashCode方法,比較的是值。

     用HashSet來(lái)驗證兩個(gè)需都重寫(xiě)的必要性

      程序提供了三個(gè)類(lèi)A,B,C,它們分別重寫(xiě)了equals(),hashCode()兩個(gè)方法中的一個(gè)或全部。
  1. public class A {
  2. @Override
  3. public boolean equals(Object obj) {
  4. return true;
  5. }
  6. }

  1. public class B {
  2. @Override
  3. public int hashCode() {
  4. return 1;
  5. }
  6. }

  1. public class C {
  2. @Override
  3. public int hashCode() {
  4. return 2;
  5. }
  6. @Override
  7. public boolean equals(Object obj) {
  8. return true;
  9. }
  10. }
  1. public class HashSetTest {
  2. public static void main(String[] args) {
  3. HashSet hashSet = new HashSet();
  4. hashSet.add(new A());
  5. hashSet.add(new A());
  6. hashSet.add(new B());
  7. hashSet.add(new B());
  8. hashSet.add(new C());
  9. hashSet.add(new C());
  10. for (Object hs : hashSet) {
  11. System.out.println(hs);
  12. }
  13. //HashSet重寫(xiě)了toString()方法
  14. // System.out.println(hashSet);
  15. }
  16. }
     其結果為:
  1. cn.edu.uestc.collection.B@1
  2. cn.edu.uestc.collection.B@1
  3. cn.edu.uestc.collection.C@2
  4. cn.edu.uestc.collection.A@3f84246a
  5. cn.edu.uestc.collection.A@18a9fa9c
  6. Process finished with exit code 0
    從上邊的程序結果可以看到,必須要同時(shí)重寫(xiě)這兩個(gè)方法,要不然Set的特性就被破壞了。

     重寫(xiě)hashCode()的原則

    (1)同一個(gè)對象多次調用hashCode()方法應該返回相同的值;
    (2)當兩個(gè)對象通過(guò)equals()方法比較返回true時(shí),這兩個(gè)對象的hashCode()應該返回相等的(int)值;
    (3)對象中用作equals()方法比較標準的Filed(成員變量(類(lèi)屬性)),都應該用來(lái)計算hashCode值。
      計算hashCode值的方法:      
  1. //f是Filed屬性
  2. boolean hashCode=(f?0:1)
  3. (byte,short,char,int) hashCode=(int)f
  4. long hashCode=(int)(f^(f>>>32))
  5. float hashCode=Float.floatToIntBits(f)
  6. double hashCode=(int)(1^(1>>>32))
  7. 普通引用類(lèi)型 hashCode=f.hashCode()
       將計算出的每個(gè)Filed的hashCode值相加返回,為了避免直接相加產(chǎn)生的偶然相等(單個(gè)不相等,加起來(lái)就相等了),為每個(gè)Filed乘以一個(gè)質(zhì)數后再相加,例如有:
return  f1.hashCode()*17+(int)f2.13
     
    查看String源碼,看hashCode()d的實(shí)現方法:


  1. /**
  2. * Returns a hash code for this string. The hash code for a
  3. * <code>String</code> object is computed as
  4. * <blockquote><pre>
  5. * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
  6. * </pre></blockquote>
  7. * using <code>int</code> arithmetic, where <code>s[i]</code> is the
  8. * <i>i</i>th character of the string, <code>n</code> is the length of
  9. * the string, and <code>^</code> indicates exponentiation.
  10. * (The hash value of the empty string is zero.)
  11. *
  12. * @return a hash code value for this object.
  13. */
  14. public int hashCode() {
  15. int h = hash;
  16. if (h == 0 && value.length > 0) {
  17. char val[] = value;
  18. for (int i = 0; i < value.length; i++) {
  19. h = 31 * h + val[i];
  20. }
  21. hash = h;
  22. }
  23. return h;
  24. }





本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
[Java面經(jīng)]干貨整理, Java面試題(覆蓋Java基礎,Java高級,JavaEE,數據庫,設計模式等)
hashcode 詳解
equals方法和hashCode方法詳解
Java集合----HashSet的實(shí)現原理
(十七):HashSet與HashMap關(guān)系之源碼分析
一文搞懂 == 、equals和hashCode
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久