首先需要明白java中HastSet實際上是用散列表實現的,散列表的大小默認大小爲16(也叫散列表元的數量),加載因子爲0,75(下面會解釋什麼是加載因子)。
去重原理:當hashset add一個元素A的時候,首先獲取這個元素的散列碼(hashcode方法),假設散列碼爲400,然後將散列碼對散列表元的數量取模,400%16=0;
0表示第一個元素,然後將元素A與散列表中的第一個鏈表中(取模爲0,所以這裏是第一個鏈表)的每個元素進行比較,(通過equals進行比較~~)如果該鏈表中沒有找到與元素A相同的元素,則將元素A添加到該鏈表,如果找到某個元素與元素A相同,則表示Set中已經存在了該元素,不添加元素A。
容量擴容原理:這裏先解釋下什麼是加載因子,當散列表中爲非空的散列表元數量除以所有散列表元的數量>加載因子的時候,hashset就會進行再散列,即將散列表大小在原有基礎上x2,對所有元素進行重新散列,得到新的散列表,以前的散列表就沒用了~~。舉個簡單的例子:假設現在hashset散列表大小爲·8,加載因子爲0,75,hastset中元素有30個,第一個鏈表包含14個元素,第二個鏈表爲空(爲空記爲0),以此類推分別爲:14 0 0 4 2 2 2 6
現在set添加第31個元素B,B的散列值爲9,9%b=1,所以將元素B與第二個鏈表中的元素進行去重比較,發現第二個鏈表爲空鏈表,所以將元素B添加到第二個鏈表。此時散列表各個鏈表的元素個數分別爲14 1 0 4 2 2 2 6,非空鏈表除以整個鏈表的大小爲7/8>0.75,這時就會進行再散列,散列表的大小爲8x2=16。當元素不斷增加時,以此類推擴容。