遍歷一個Set的方法只有一個:迭代器(interator)。

Set-HashSet實現類:算法

遍歷一個Set的方法只有一個:迭代器(interator)。數組

HashSet中元素是無序的(這個無序指的是數據的添加順序和後來的排列順序不一樣),並且元素不可重複。code

Object中除了有final()toString()equals(),還有hashCode()對象

HashSet底層用的也是數組。接口

當向數組中利用add(Object o)添加對象的時候,系統先找對象的hashCodestring

int hc=o.hashCode(); 返回的hashCode爲整數值。hash

Int I=hc%n;n爲數組的長度),取得餘數後,利用餘數向數組中相應的位置添加數據,以n6爲例,若是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對象,不容許重複,而且遍歷出來。

相關文章
相關標籤/搜索