HashSet中重寫haseCode和equals

山有木xi發表於2020-02-29

為了儲存數量不確定的資料,以及儲存具有對映關係的資料,Java提供了集合類

集合中的Set,類似一個大罐子,可以依次把1至多個物件存入Set集合,Set集合通常無法記住元素的新增順序

而Set集合中不允許包含兩個相同的元素加入同一個Set集合中,在多個執行緒同時訪問同一個HashSet時,多個執行緒同時修改HashSet集合時,則必須透過程式碼來保證其同步

那麼HashSet是怎麼樣區分不同元素的?這就要說到了 hashCode和equals

在HashSet集合加了一個元素時, HashSet會呼叫該物件的 hashCode方法來得到該物件的hashCode值,然後根據hashCode值決定該物件在HashSet中的位置,如果兩個元素透過equals方法比較返回true,但他們的hashCode方法返回值不相等,HashSet將會把他們存放在不同的位置,依然可以新增成功

也就是說HashSet辨別元素是否相同是透過equals判斷相等加上對比hashCode值

下面看一段程式碼

class h
{
   public boolean equals( object obj)
{
        return true;
}
}
class z
{
   public int hashCode()
{
        return 1;
}
}
class t
{
   public int hashCode()
{
        return 2;
}
   public boolean equals( object obj)
{
        return true;
}
}
public class HashSetTest
{
  public static void main(String[] args)
  {
  var b=new HashSet();
  b.add(new h);
  b.add(new h);
  b.add(new z);
  b.add(new z);
  b.add(new t);
  b.add(new t);
  System.out.println(b);
  }
}

結果是:

h@5674dd,h@0987as,z@1,z@1,t@2

也就是說,

兩個h物件透過equals方法比較返回true,但HashSet依然把他們當做兩個物件

兩個z物件透過hashCode返回相同值, 但HashSet依然把他們當做兩個物件

兩個t物件 透過equals方法比較返回true透過hashCode返回相同值,此時, HashSet才將他們當為一個物件

可見:當把一個物件放入HashSet中如果重寫 equals 就應該重寫 hashCode

equals對比兩個物件相等時,如果hashCode不同,則會將兩個相同的元素新增入 HashSet,這就和Set集合的規 則衝突

此時,還有一種極端情況:如果hashCode相等,而equals不同,會怎麼樣呢?

那麼,將會更麻煩,HashSet試圖將他們放在一起,但是又不行

所以, 將會採用鏈式結構,儲存多個物件,進而影響效能,導致效能下降

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69917874/viewspace-2677836/,如需轉載,請註明出處,否則將追究法律責任。

相關文章