來說說HashSet。如果有點Java基礎的童鞋,應該都知道List和Set都實作自Collection,List保證元素的添加順序,元素可重複。而Set不保證元素的添加順序,元素不可重複。

建立一個 HashSet如下:
Set<String> strSet = new HashSet<>();//new了一個HashSet
new了一個HashSet,前面的文章已經說過很多次了,隻要是看到new,這貨肯定在堆記憶體裡開辟了一塊空間,先找到HashSet的構造函數看看,看到如下代碼:
等等,怎麼出現了HashMap,這個HashMap到底是什麼鬼?再看一下map,追蹤一下
就是一個HashMap,老規矩畫圖吧
如上圖,當我們執行 Set<String> strSet = new HashSet<>(); 時,在棧空間會建立一個 strSet引用,這個引用指向 堆空間 的HashSet對象,然後這個堆對象中又有 指向 HashMap的引用。
繼續執行以下代碼,往strSet添加元素"張三"
strSet.add("張三");
再看add方法
原來就是調用底層HashMap的put方法,把"張三"作為key,PRESENT作為value放在hashMap裡,我們知道在HashMap裡,如果put時key重了,會傳回被覆寫的value值(oldValue),否則傳回null,這兒的HashSet又給包裝了一下,如果key沒有重(oldValue == null),就傳回true,否則傳回false。繼續看這個PRESENT是什麼鬼
很簡單就是new了一個Object,繼續畫圖
調用底層HashMap的時候,key是傳進去的“張三”,value是PRESENT,也就是一個Object對象,繼續往裡添加“李四”,“王五”,“趙六”
strSet.add("李四");
strSet.add("王五");
strSet.add("趙六");
依次放入“李四”,“王五”,“趙六”,value都是一樣的,為PRESENT,繼續畫圖
所有元素的value都指向Object對象,HashSet雖然底層是用HashMap來實作的,但由于用不到HashMap的value,是以不會為底層HashMap的每個value配置設定一個記憶體空間,是以并不會過多的占用記憶體,請放心使用。這些方法基本上沒什麼邏輯代碼,就是複用了HashMap裡的方法而已。HashSet就是利用HashMap來實作的。
小結:HashSet底層聲明了一個HashMap,HashSet做了一層包裝,操作HashSet裡的元素時其實是在操作HashMap裡的元素。