<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          JavaBean,為什么要重寫hashCode()方法和equals()方法及如何重寫

          共 9881字,需瀏覽 20分鐘

           ·

          2021-09-02 22:47

          程序員的成長之路
          互聯(lián)網(wǎng)/程序員/技術/資料共享 
          關注


          閱讀本文大概需要 4 分鐘。

          來自:blog.csdn.net/qq_36090463/article/details/81102713

          JavaBean為什么要重寫hashCode()方法和equals方法,我記得當時我巴拉巴拉半天就是沒有說到重點.

          現(xiàn)在想一想歸根到底還是我對這兩個的理解不深刻,現(xiàn)在我特定來總結(jié)下.hashCode 方法用于散列集合的查找,equals 方法用于判斷兩個對象是否相等。

          一、我們?yōu)槭裁葱枰貙慼ashCode()方法和equals()方法?(Why)

          有時在我們的業(yè)務系統(tǒng)中判斷對象時有時候需要的不是一種嚴格意義上的相等,而是一種業(yè)務上的對象相等。在這種情況下,原生的equals方法就不能滿足我們的需求了.

          我們所知道的JavaBean的超類(父類)是Object類,JavaBean中的equals方法是繼承自Object中的方法.Object類中定義的equals()方法是用來比較兩個引用所指向的對象的內(nèi)存地址是否一致.并不是比較兩個對象的屬性值是否一致,所以這時我們需要重寫equals()方法.

          Object類中equals()方法的源碼

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

          public class Demo {
           public static void main(String[] args) {
            Student stu1 = new Student("awu",22);
            Student stu2 = new Student("awu",22);
            System.out.println(stu1.equals(stu2));
                          /*因為Student這個JavaBean沒有重寫關于屬性值相等的equals()方法
                            ,所以默認比較的是地址值,從而輸出結(jié)果為false*/
              
           }
          }

          那么為什么在重寫equals方法的時候需要重寫hashCode方法呢?

          主要是Object.hashCode的通用約定:

          • 在java應用程序運行時,無論何時多次調(diào)用同一個對象時的hsahCode()方法,這個對象的hashCode()方法的返回值必須是相同的一個int值.
          • 如果兩個對象equals()返回值為true,則他們的hashCode()也必須返回相同的int值.
          • 如果兩個對象equals()返回值為false,則他們的hashCode()返回值也必須不同.

          以HashSet來說明為什么要這么約定:HashSet存放元素時,根據(jù)元素的hashCode值快速找到要存儲的位置,如果這個位置有元素,兩個對象通過equals()比較,如果返回值為true,則不放入;如果返回值為false,則這個時候會以鏈表的形式在同一個位置上存放兩個元素,這會使得HashSet的性能降低,因為不能快速定位了。

          還有一種情況就是兩個對象的hashCode()返回值不同,但是equals()返回true,這個時候HashSet會把這兩個對象都存進去,這就和Set集合不重復的規(guī)則相悖了;所以,我們重寫了equals()方法時,要按照b,c規(guī)則重寫hashCode()方法!(其實就是如果只重寫了 equals 方法,兩個對象 equals 返回了true,但是如果沒有重寫 hashCode 方法,集合還是會插入元素。這樣集合中就出現(xiàn)了重復元素了。)

          二、在什么情況下需要重寫hashCode()方法和equals()方法? (When)

          當我們自定義的一個類,想要把它的實例保存在以Hash散列查找的集合中時,我們就需要重寫這兩個方法;

          public class Student {
           private String name;
           
           private Integer age;
           
           public Student(){
            
           }
           
           public Student(String name,Integer age){
            this.name = name;
            this.age = age;
           }
           
           public String getName() {
            return name;
           }
           
           public void setName(String name) {
            this.name = name;
           }
           
           public Integer getAge() {
            return age;
           }
           
           public void setAge(Integer age) {
            this.age = age;
           }
           
           @Override  
              public int hashCode(){  
                  final int prime = 31;  
                  int result = 17;  
                  result = prime * result + name.hashCode();  
                  result = prime * result + age;  
                  return result;  
              }  
           
              @Override  
              public boolean equals(Object obj){  
                  if(this == obj)  
                      return true;  
                  if(obj == null)  
                      return false;  
                  if(getClass() != obj.getClass())  
                      return false;  
                  final Student other = (Student)obj;  
                  if(name.equals(other.name)){  
                      return false;  
                  }  
                  if(age.equals(other.age)){  
                      return false;  
                  }  
                  return true;  
              }  
           
          }

          public class Demo {
           public static void main(String[] args) {
            Student stu1 = new Student("awu",22);
            Student stu3 = new Student("awu",33);
            Student stu2 = new Student("awu",22);
            
            Set set = new HashSet();
            set.add(stu1);
            set.add(stu2);
            set.add(stu3);
            
            System.out.println(set.size());
                          /*輸出結(jié)果為2*/
            
           }
          }

          如果不是以Hash散列查找的集合,即使重寫HashCode也沒多大實際用處.比如如下栗子:

          public class Demo {
           public static void main(String[] args) {
            Student stu1 = new Student("awu",22);
            Student stu3 = new Student("awu",33);
            Student stu2 = new Student("awu",22);
            
            ArrayList list = new ArrayList();
            list.add(stu1);
            list.add(stu2);
            list.add(stu3);
            
            System.out.println(list .size());
                          /*輸出結(jié)果為3*/
            
           }
          }

          三、如何重寫這兩個方法?(How)

          public class Student {
           private String name;
           
           private Integer age;
           
           public Student(){
            
           }
           
           public Student(String name,Integer age){
            this.name = name;
            this.age = age;
           }
           
           public String getName() {
            return name;
           }
           
           public void setName(String name) {
            this.name = name;
           }
           
           public Integer getAge() {
            return age;
           }
           
           public void setAge(Integer age) {
            this.age = age;
           }
           
               @Override  
                  public int hashCode(){  
                      final int prime = 31;  
                      int result = 17;  
                      result = prime * result + name.hashCode();  
                      result = prime * result + age;  
                      return result;  
                  }  
           
                  @Override  
                  public boolean equals(Object obj){  
                      if(this == obj)  
                          return true;  
                      if(obj == null)  
                          return false;  
                      if(getClass() != obj.getClass())  
                          return false;  
                          final Student other = (Student)obj;  
                      if(name.equals(other.name)){  
                          return false;  
                      }  
                      if(age.equals(other.age)){  
                          return false;  
                      }  
                      return true;  
              }  
           
          }

          <END>

          推薦閱讀:

          密碼打馬賽克已經(jīng)不安全了!這款開源的去“馬賽克”工具一秒還原

          多賬號統(tǒng)一登陸,賬號模塊的系統(tǒng)設計

          最近面試BAT,整理一份面試資料《Java面試BATJ通關手冊》,覆蓋了Java核心技術、JVM、Java并發(fā)、SSM、微服務、數(shù)據(jù)庫、數(shù)據(jù)結(jié)構(gòu)等等。

          獲取方式:點個「在看」,點擊上方小卡片,進入公眾號后回復「面試題」領取,更多內(nèi)容陸續(xù)奉上。

          朕已閱 

          瀏覽 38
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  五月天成人在线视频免费播放 | 成人天天爽 | 激情五月天的婷婷 | 色男人色天堂 | 免费看黄色视频久久 |