<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()方法及如何重寫

          共 9659字,需瀏覽 20分鐘

           ·

          2021-09-03 10:30

          JavaBean為什么要重寫hashCode()方法和equals方法,我記得當(dāng)時(shí)我巴拉巴拉半天就是沒(méi)有說(shuō)到重點(diǎn).

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

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

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

          我們所知道的JavaBean的超類(父類)是Object類,JavaBean中的equals方法是繼承自O(shè)bject中的方法.Object類中定義的equals()方法是用來(lái)比較兩個(gè)引用所指向的對(duì)象的內(nèi)存地址是否一致.并不是比較兩個(gè)對(duì)象的屬性值是否一致,所以這時(shí)我們需要重寫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));
                          /*因?yàn)镾tudent這個(gè)JavaBean沒(méi)有重寫關(guān)于屬性值相等的equals()方法
                            ,所以默認(rèn)比較的是地址值,從而輸出結(jié)果為false*/
              
           }
          }

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

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

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

          以HashSet來(lái)說(shuō)明為什么要這么約定:HashSet存放元素時(shí),根據(jù)元素的hashCode值快速找到要存儲(chǔ)的位置,如果這個(gè)位置有元素,兩個(gè)對(duì)象通過(guò)equals()比較,如果返回值為true,則不放入;如果返回值為false,則這個(gè)時(shí)候會(huì)以鏈表的形式在同一個(gè)位置上存放兩個(gè)元素,這會(huì)使得HashSet的性能降低,因?yàn)椴荒芸焖俣ㄎ涣恕?/p>

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

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

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

          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也沒(méi)多大實(shí)際用處.比如如下栗子:

          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*/
            
           }
          }

          三、如何重寫這兩個(gè)方法?(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;  
              }  
           
          }
          (感謝閱讀,希望對(duì)你所有幫助)
          來(lái)源:blog.csdn.net/qq_36090463/
          article/details/81102713
          瀏覽 27
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  中文字幕日产A片在线看 | 丁香五月婷婷小说 | 青草青视频在线 | 逼特逼视频免费观看 | 波多野结衣无码一区二区 |