==和equals和hashCode的理解

來源:互聯網
上載者:User

      今天做面試題的時候遇到了一個問題,問題的代碼如下:

      

import java.util.HashMap;import java.util.Map;public final class PhoneNumber {   private final short areaCode;   private final short prefix;   private final short lineNumber;   public PhoneNumber(int areaCode,int prefix,int lineNumber){   rangeCheck(areaCode, 999, "area code");   rangeCheck(prefix, 999, "prefix");   rangeCheck(lineNumber, 9999, "line number");   this.areaCode=(short)areaCode;   this.prefix=(short)prefix;   this.lineNumber=(short)lineNumber;   }   private static void rangeCheck(int arg,int max,String name){   if(arg<0||arg>max){   throw new IllegalArgumentException(name+":"+arg);   }   }@Overridepublic boolean equals(Object o) {  if(o==this)  return true;  if(!(o instanceof PhoneNumber))  return false;  PhoneNumber pn=(PhoneNumber) o;  return (pn.lineNumber==lineNumber)&&(pn.prefix==prefix)&&(pn.areaCode==areaCode);return false;  } public static void main(String[] args){ Map<PhoneNumber, String> m=new HashMap<PhoneNumber, String>(); PhoneNumber pn=new PhoneNumber(707,067, 5309); m.put(new PhoneNumber(707,067, 5309), "jenny"); System.out.println(m.get(new PhoneNumber(707,067, 5309))); }}   

 

       而問題就是看看程式執行完後的輸出結果,我當時一看此題有個疑問但是不確定,他沒有重寫hashCode方法,又想起equals方法與hashCode的方法建議是一起出現的,所以想到此題有陷阱,但是又不知道什麼地方有陷阱。把程式敲了一遍發現輸出結果為null,猜到肯定與hashCode相關,於是在Map的put方法前加了一個端點,進入了hashmap的源碼進行單步調試,我發現源碼中在存取key的時候調用了hashcode方法,而預設如果不重寫hashcode方法是調用的預設的hashcode,即對象的雜湊碼,所以不同的對象有不同的雜湊碼,然後他根據雜湊碼進行儲存。當調用get方法時又根據雜湊碼進行取值,如果值存在才進行eqals方法的調用,所以即使equals方法返回是true也是沒有用的需要重寫hashCode讓其返回相同的雜湊碼。我將代碼改成如下形式後返回了jenny。

   

import java.util.HashMap;import java.util.Map;public final class PhoneNumber {   private final short areaCode;   private final short prefix;   private final short lineNumber;   public PhoneNumber(int areaCode,int prefix,int lineNumber){   rangeCheck(areaCode, 999, "area code");   rangeCheck(prefix, 999, "prefix");   rangeCheck(lineNumber, 9999, "line number");   this.areaCode=(short)areaCode;   this.prefix=(short)prefix;   this.lineNumber=(short)lineNumber;   }   private static void rangeCheck(int arg,int max,String name){   if(arg<0||arg>max){   throw new IllegalArgumentException(name+":"+arg);   }   }@Overridepublic boolean equals(Object o) {  if(o==this)  return true;  if(!(o instanceof PhoneNumber))  return false;  PhoneNumber pn=(PhoneNumber) o;  return (pn.lineNumber==lineNumber)&&(pn.prefix==prefix)&&(pn.areaCode==areaCode);return false;  }@Overridepublic int hashCode(){return 7*(new Integer(lineNumber).hashCode())+11*(new Integer(prefix)).hashCode()+13*(new Integer(areaCode).hashCode());} public static void main(String[] args){ Map<PhoneNumber, String> m=new HashMap<PhoneNumber, String>(); PhoneNumber pn=new PhoneNumber(707,067, 5309); m.put(new PhoneNumber(707,067, 5309), "jenny"); System.out.println(m.get(new PhoneNumber(707,067, 5309))); System.out.println(pn.getClass()); }}      

 

現在說一下equals方法和==的區別,==預設是比較兩個對象的引用是否相等,equsls如果沒被重寫預設也是按照==進行比較。==一般用來比較兩個基本類型是否相等,我們在比較字串相等的時候也用equals方法,那是因為在String類中已經將equals方法和hashCode方法進行了覆寫,比較的是值的大小。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.