在說hashset集合怎麼儲存自定義物件細節之前,先看看hashset類的特點吧。
通過查閱api,發現hashset集合:
1、 hashset集合底層使用雜湊表結構
2、 hashset集合中的儲存的元素是無序的
3、 因為繼承了set介面,所以不能儲存重複元素
4、 允許儲存null元素,但是只能有乙個
5、效能:查詢元素和儲存不重複元素的效率比較高
既然,hashset集合底層使用雜湊表,再來說說雜湊表是什麼個東西吧?
hashset集合底層雜湊表儲存元素的過程:
1、 在向hashset集合中儲存元素時,會先拿要儲存的元素和雜湊演算法結合,計算出雜湊值(元素的儲存位置)。
2、 判斷計算出的儲存位置上是否已經有元素存在了
有元素存在:拿要儲存的元素和已經存在的元素進行equals比較
equasl結果:相同 ,表示重複元素。不做儲存操作
equals結果:不相同, 繼續計算新的儲存位置(常用作法:拉鍊法)
拉鍊法:會使用當前儲存位置和雜湊演算法繼續計算新的儲存位置,再判斷新的儲存位置上是否有元素存在(和之前方案類同)
沒元素存在:直接把元素存到該位置上
到這裡,大家有沒有疑問,儲存的元素怎麼去和演算法結合的呢?
筆者當初在此處也很疑惑,當我們向hashset集合中新增元素時,使用add方法時,並沒有看到演算法,那麼儲存的元素怎麼和演算法結合的呢?
在這裡我們思考下面兩個問題:
思考:集合中只能儲存什麼型別的元素? 引用型別
思考:引用型別的元素有父類嗎? 最高父類是object
對,你猜對了。在object 類中存在乙個功能,可以用來計算雜湊值
好了,說了那麼多關於雜湊表底層的內容,我們再言歸正題,筆者通過乙個案例來說明怎麼才能儲存自定義物件不重複呢?
package com.hmtest.demo;
public class person
public void setname(string name)
public int getage()
public void setage(int age)
@override
public string tostring()
public person(string name, int age) }
public class hashsettest }}
輸出結果:
為什麼以在程式執行後,還會出現重複的物件呢?
這是因為在向集合中儲存元素時,拿person物件和雜湊演算法結合計算出雜湊值。而建立的person物件不同,所以在和雜湊演算法計算時,也就產生不同的雜湊值(沒有呼叫equals方法判斷是否相等)。
解決方案:1,讓儲存的元素使用同乙個雜湊值,就會呼叫equals方法比較
具體做法是:在person類中重寫object類中的hashcode方法,新增如下**:
public int hashcode()
2,在計算出相同的雜湊值後,還會存在equals比較物件,產生物件不相同結果。所以還需要在person中重寫object類中的equals方法。
具體做法如下:在person類中重寫object類中equals方法(比較物件中的內容)
public boolean equals(object obj)
也許你看到上面步驟會抓狂,請不要激動,eclipse會懂你的。。你只需要按照下面的方法,eclipse會為你自動生成
shift+alt+s>>>>選擇gerate hascode()and equals()系統會自動幫你生成所需要重寫的**。
讓我們再來看看結果吧,結果終於是我們想要的啦!無重複的元素啦
自定義集合型別
很多時候我們去自定義一些型別,更有些時候我們會把這些自定義型別封裝成集合,比如說現在有乙個自定義型別user 使用者 class user 使用者名稱 public string username 使用者這密碼 public string password 一般情況下,我們封裝集合時,是用泛型的li...
自定義集合型別
很多時候我們去自定義一些型別,更有些時候我們會把這些自定義型別封裝成集合,比如說現在有乙個自定義型別user 使用者 class user 使用者名稱 public string username 使用者這密碼 public string password 一般情況下,我們封裝集合時,是用泛型的li...
C 自定義集合
自定義型別 public class product 自增id public string name 名稱 public string code 主鍵 public string category 型別 public decimal price public datetime producedate...