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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于equals和hashcode方法

發布時間:2024/4/17 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于equals和hashcode方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

首先聲明一下,這篇文章僅僅討論引用類型

所有引用類型都是繼承自Object類,Object類有兩個重要的方法:equals(),hashCode()經常被使用,雖然表面上你可能看不到你的代碼里使用hashcode()。

Object類是這樣實現equals方法的:

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

可見默認情況下==和equals()方法是一樣的,即比較兩個對象的地址。

從技術上來說,只要是通過new創建出來的實例,任何情況下equals和==都是false;

從業務上來說,有的時候我們希望即使不是同一個實例也可以相等:比如在系統中的不同組件之間,可以傳遞具有相同身份證信息的人的不同實例,但是在各個組件看來,這些不同實例對應的應該是同一個人,因為他們具有相同的身份證信息!

所以在開發過程中就產生了==不相等但是需要equals相等的矛盾!(因為==我們無法改變,所以業務邏輯只能寄希望于改變equals的實現)。

以身份證為某個人唯一標示作為例子,我們定義的時候應該是這樣的:

1 /** 2 * 具有相同身份證信息的人就是同一個人 3 * 4 * @author Lucifer 5 * 6 */ 7 public class Person { 8 9 private String name; 10 private String identityCard; 11 12 public Person(String name, String identityCard) { 13 this.name = name; 14 this.setIdentityCard(identityCard); 15 } 16 17 public String getName() { 18 return name; 19 } 20 21 public void setName(String name) { 22 this.name = name; 23 } 24 25 public String getIdentityCard() { 26 return identityCard; 27 } 28 29 public void setIdentityCard(String identityCard) { 30 this.identityCard = identityCard; 31 } 32 33 @Override 34 public boolean equals(Object obj) { 35 if (obj == null) { 36 return false; 37 } 38 if (!(obj instanceof Person)) { 39 return false; 40 } 41 Person person = (Person) obj; 42 43 return person.getIdentityCard().equals(this.identityCard); 44 45 } 46 } Person類

說到這里終于可以進入正題了,因為我們有了需要改變equals規則的需求。Object的hashcode有一些規約:

Returns a hash code value for the object. This method is supported for the benefit of hashtables such as those provided by java.util.Hashtable.

The general contract of hashCode is:

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
  • It is not required that if two objects are unequal according to the java.lang.Object.equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.

As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)

紅色字體部分經常被面試官問道,所以不管你想不想真正理解,你都應該記住:

1.如果兩個object通過equals方法判斷為相等,那么hashcode方法必須返回相同的整型值。

2.如果兩個object通過equals方法判斷為不相等,那么hashcode方法不要求必須返回不相等的整型值。但是程序員應該為不相等(通過equals方法判斷的)的object返回不同的hashcode,以提高hashtables的性能。

這是我們就想到這個跟HashTable有什么關系呢,雖然沒有強制不相等的時候重寫hashCode方法,但是建議我們重寫以提高HashTable的性能。

那么如何重寫hashCode呢?

最簡單的方法:如果你使用Eclipse開發,那么在需要重寫hashCode和equals的類中右鍵選擇source->Generate hashcode and equals

上面我們的例子用這個方法生成的代碼如下:

1 /** 2 * 具有相同身份證信息的人就是同一個人 3 * 4 * @author Lucifer 5 * 6 */ 7 public class Person { 8 9 private String name; 10 private String identityCard; 11 12 public Person(String name, String identityCard) { 13 this.name = name; 14 this.setIdentityCard(identityCard); 15 } 16 17 public String getName() { 18 return name; 19 } 20 21 public void setName(String name) { 22 this.name = name; 23 } 24 25 public String getIdentityCard() { 26 return identityCard; 27 } 28 29 public void setIdentityCard(String identityCard) { 30 this.identityCard = identityCard; 31 } 32 33 @Override 34 public int hashCode() { 35 final int prime = 31; 36 int result = 1; 37 result = prime * result 38 + ((identityCard == null) ? 0 : identityCard.hashCode()); 39 result = prime * result + ((name == null) ? 0 : name.hashCode()); 40 return result; 41 } 42 43 @Override 44 public boolean equals(Object obj) { 45 if (this == obj) 46 return true; 47 if (obj == null) 48 return false; 49 if (getClass() != obj.getClass()) 50 return false; 51 Person other = (Person) obj; 52 if (identityCard == null) { 53 if (other.identityCard != null) 54 return false; 55 } else if (!identityCard.equals(other.identityCard)) 56 return false; 57 if (name == null) { 58 if (other.name != null) 59 return false; 60 } else if (!name.equals(other.name)) 61 return false; 62 return true; 63 } 64 } View Code

如果加上一個int類型的字段age,生成的代碼如下:

1 @Override 2 public int hashCode() { 3 final int prime = 31; 4 int result = 1; 5 result = prime * result + age; 6 result = prime * result 7 + ((identityCard == null) ? 0 : identityCard.hashCode()); 8 result = prime * result + ((name == null) ? 0 : name.hashCode()); 9 return result; 10 }

因為對于基本類型他們的值就是他們的HashCode。

當然,我們還注意到hashCode方法返回的是int類型。那按以上的實現方式會不會出現問題呢,比如我們把age改成long:

1 @Override 2 public int hashCode() { 3 final int prime = 31; 4 int result = 1; 5 result = prime * result + (int) (age ^ (age >>> 32)); 6 result = prime * result 7 + ((identityCard == null) ? 0 : identityCard.hashCode()); 8 result = prime * result + ((name == null) ? 0 : name.hashCode()); 9 return result; 10 }

對于超出int類型長度的long類型,只需要做一下位移操作,保證不超出int范圍即可。

最后,奉上一段國外程序員給出的重寫hashCode方法的原則:

1) Take a prime hash e.g. 5, 7, 17 or 31 (prime number as hash, results in distinct hashcode for distinct object) 2) Take another prime as multiplier different than hash is good. 3) Compute hashcode for each member and add them into final hash. Repeat this for all members which participated in equals. 4) Return hash

Read more:?http://javarevisited.blogspot.com/2011/10/override-hashcode-in-java-example.html#ixzz3YHnchQTu

轉載于:https://www.cnblogs.com/mayongsheng/p/4455570.html

總結

以上是生活随笔為你收集整理的关于equals和hashcode方法的全部內容,希望文章能夠幫你解決所遇到的問題。

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