Set-HashSet實現類:算法
遍歷一個Set的方法只有一個:迭代器(interator)。數組
HashSet中元素是無序的(這個無序指的是數據的添加順序和後來的排列順序不一樣),並且元素不可重複。code
在Object中除了有final(),toString(),equals(),還有hashCode()。對象
HashSet底層用的也是數組。接口
當向數組中利用add(Object o)添加對象的時候,系統先找對象的hashCode:string
int hc=o.hashCode(); 返回的hashCode爲整數值。hash
Int I=hc%n;(n爲數組的長度),取得餘數後,利用餘數向數組中相應的位置添加數據,以n爲6爲例,若是I=0則放在數組a[0]位置,若是I=1,則放在數組a[1]位置。若是equals()返回的值爲true,則說明數據重複。若是equals()返回的值爲false,則再找其餘的位置進行比較。這樣的機制就致使兩個相同的對象有可能重複地添加到數組中,由於他們的hashCode不一樣。效率
若是咱們可以使兩個相同的對象具備相同hashcode,才能在equals()返回爲真。遍歷
在實例中,定義student對象時覆蓋它的hashcode。迭代器
由於String類是自動覆蓋的,因此當比較String類的對象的時候,就不會出現有兩個相同的string對象的狀況。
如今,在大部分的JDK中,都已經要求覆蓋了hashCode。
結論:如將自定義類用hashSet來添加對象,必定要覆蓋hashcode()和equals(),覆蓋的原則是保證當兩個對象hashcode返回相同的整數,並且equals()返回值爲True。
若是偷懶,沒有設定equals(),就會形成返回hashCode雖然結果相同,但在程序執行的過程當中會屢次地調用equals(),從而影響程序執行的效率。
咱們要保證相同對象的返回的hashCode必定相同,也要保證不相同的對象的hashCode儘量不一樣(由於數組的邊界性,hashCode仍是可能相同的)。例子:
public int hashCode(){
return name.hashcode()+age;
}
這個例子保證了相同姓名和年齡的記錄返回的hashCode是相同的。
使用hashSet的優勢:
hashSet的底層是數組,其查詢效率很是高。並且在增長和刪除的時候因爲運用的hashCode的比較開肯定添加元素的位置,因此不存在元素的偏移,因此效率也很是高。由於hashSet查詢和刪除和增長元素的效率都很是高。
可是hashSet增刪的高效率是經過花費大量的空間換來的:由於空間越大,取餘數相同的狀況就越小。HashSet這種算法會創建許多無用的空間。
使用hashSet接口時要注意,若是發生衝突,就會出現遍歷整個數組的狀況,這樣就使得效率很是的低。
練習:new一個hashset,插入employee對象,不容許重複,而且遍歷出來。