因為會設計到很多equal的知識,所以先深入理解一下equals().
object類中的預設equals()方法和==是沒有區別的,都是判斷兩個物件是否指向同乙個引用,記憶體位址是否相同,即是否就是乙個物件。而string類和integer等,都需要重寫equals()方法,用來判斷兩個物件的值是否相等,而不是記憶體位址是否相同。所以,如果元素要儲存到hashset集合中,必須覆蓋equals方法。
這邊有個細節,當我們建立類的時候,預設繼承object裡面的equal,而集合裡面有方法比如contains(),還有remove(),判斷是否包含某個元素和移除元素,它得底層也是通過equal來判斷的,所以一定要注意根據自己的需求來重新定義equals。其他的集合物件裡面也是這樣,只是資料結構不同,判斷結構稍有差距。
hashset: 內部資料結構是雜湊表 ,是不同步的。
如何保證該集合的元素唯一性呢?
是通過物件的hashcode和equals方法來完成物件唯一性的。
如果物件的hashcode值不同,那麼不用判斷equals方法,就直接儲存到雜湊表中。
如果物件的hashcode值相同,那麼要再次判斷物件的equals方法是否為true。
如果為true,視為相同元素,不存。如果為false,那麼視為不同元素,就進行儲存。
為什麼要使用hashcode這種方法呢?
所以:如果元素要儲存到hashset集合中,必須覆蓋hashcode方法和equals方法。
首先我們來看第乙個例子:建立乙個student物件,包含name和age兩個屬性。
public class hashsettest
}}
那麼我們知道,set集合物件中元素是唯一的,那按理,第一條和最後一條是重複的,只應該留下乙個,那為什麼兩個都留下來了呢?
第乙個原因就是euqals方法,我們知道,set通過equal來判斷兩個物件是否相等,而在object中,euqal的作用是和==一樣的,就是判斷兩個物件是否相等而不是相同,就是是否指向同乙個引用,顯然,我們new了五個不同的物件,所以在記憶體中他們的位址都是不同的,所以equals判斷是五個不同的物件,當然都存了進來。所以我們得把判斷是否相等得依據封裝到equals()方法中。
第二個原因就是hashcode,我們並沒有重寫hashcode方法,還是用預設的hashcode的方法。
所以我們在student重寫兩個方法
@override
public int hashcode()
@override
public boolean equals(object obj)
首先給每個物件算出hash值,如果相等了,在呼叫equals方法。
public static void main(string args) */
}
因為hashset是基於hashmap實現的,它的add方法也是基於hashmap的put方法實現的,所以我們來看hashmap的add方法。
public v put(k key, v value)
}modcount++;
addentry(hash, key, value, i);
return null;
}
public static void main(string args)
我們remove了乙個,那集合的size應該還剩2,但是測試結果size還是3.這就是大問題了,不用的物件結果還在記憶體當中,那這樣時間長了記憶體肯定會滿了。為什麼會這樣呢?以下為remove原始碼。hashset的emove方法同樣是以hashmap的remove方法為基礎的,我們直接看hashmap的remove()。
public v remove(object key)
這邊又出現了乙個removeentrykey().再看。
final entryremoveentryforkey(object key)
prev = e;
e = next;
}return e;
}
equals和hashcode的重寫
下面給出例項 package xuming class student public student string name,int age,int classnum 重寫equals方法 public boolean equals object o 測試引用o是都為null if o null 測...
equals 和hashCode 的區別
equals 反映的是或變數具體的值,即兩個物件包含的值 可能是物件的引用,也可能是值型別的值 hashcode 計算出物件例項的雜湊碼 根據記憶體位址返回的int型的數值 並返回雜湊碼,又稱為雜湊函式。根據object的hashcode都是唯一的 當然,當物件重寫了hashcode 方法時,結果就...
equals 和hashCode 使用總結
equals package cn.galc.test public class testequals 沒有重寫equals class cat 先判斷比較物件是否為null 判斷比較物件是否為要比較類的例項 比較倆個成員變數是否完全相等。public class testequals 重寫equa...