java 爲什麼要重寫equals()和hashcode()

爲什麼要重寫equals()和hashcode()

在java裏集合類是使用十分頻繁的數據類型,Collection類中定義了一個方法是.contains(),不知道小夥伴們是否遇到過使用.contains()一直返回false,明明某個元素就在集合中的情況,反正我是遇到了。。。

那爲什麼會出現這種情況呢?其實Collection實現contains方法是通過調用equals()來將參數和集合中的每個元素進行比較的。那麼問題來了,對於我們自己寫的可變類型的類,若沒用重寫equals方法的話,就會出問題。看下面這個例子:

class Vertex{
private String name;
 public Vertex(String vertex) {
  name = vertex;
 }
 public void setName(String cString) {
  name = cString;
 }
 public String getName() {
  return name;
 }
}

public static void main(String[] args)
 {
  String nString = "hhhh";
  Vertex vertex = new Vertex(nString);
  Vertex vertex2 = new Vertex(nString);
  if ( vertex.equals(vertex2))
   System.out.println("true");
  else {
   System.out.println("false");
  }
  vertex2.setName("hhhhh");
  if ( vertex.equals(vertex2))
   System.out.println("true");
  else {
   System.out.println("false");
  }
}

上述代碼運行的結果按道理來說應該是true和false對吧,但其實是false和false。

在這裏插入圖片描述
那好,我們對class Vertex作出修改,重寫它的equals()和hashcode()方法,想偷懶的同學也可以用eclipse自動生成,但要確保滿足等價性,也就是對稱,自反,傳遞。生成方法也是右鍵source–>Generate equals() and hashcode(),變成如下這樣,也就是加上了equals和hashcode以後:

class Vertex{
private String name;
 public Vertex(String vertex) {
  name = vertex;
 }
 public void setName(String cString) {
  name = cString;
 }
 public String getName() {
  return name;
 }
 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + ((name == null) ? 0 : name.hashCode());
  return result;
 }
 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  Vertex other = (Vertex) obj;
  if (name == null) {
   if (other.name != null)
    return false;
  } else if (!name.equals(other.name))
   return false;
  return true;
 }
}

然後我們在運行,這時候打印輸出纔是true和false了。

所以,如果你要用contains()方法,就必須得重寫equals和hashcode,這裏我只是舉例個例子,想了解更多的小夥伴可以去找其他博客看看或者直接看collection的接口方法的實現。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章