set如何理解無序,不可重復性
以hashset為例
-
無序性:無序性不等於隨機性,存儲的數據在底層數組中並非按照數組索引的順序添加,而是數據的hashcode值來決定的
-
不可重復:保證添加的元素,按照equals()判斷時,不能返回true,即相同的元素只能添加一個
先hashset中添加元素a,首先會元素a所在類的hashcode,計算元素a的hash值,此時哈希值通過某種算法,計算出在hashset底層數組中存放的位置(即為索引位置),
判斷數組此位置上是否有元素,如果沒有元素,,則元素a添加成功
如果此位置上有其他元素B(或者以鏈表形式存在的多個元素),則比較a與存在元素的hash值
如果hash值不同,則元素a添加成功-------------->情況1
如果hash值相同,進而需要調用元素a所在類的equals方法,如果返回true,則a添加失敗
如果返回false,則添加成功------------>情況2
對於情況一,情況二,添加成功的元素則以鏈表的方式存儲
jdk7:元素a放到數組中,指向原來的元素
Jdk8:原來的元素指向元素a;
總結:七上八下
(set接口中沒有定義新的方法,使用的都是collection接口中的方法
要求:向set中添加數據,其所在的類一定要重寫hashcode方法和equals方法
要求:重寫的hashCode和equals方法盡可能保證一致性,即相等的對象必須具有相同的散列碼
)
補充
LinkedHashSet作為hashset的子類,在添加數據的同時,每個數據還維護了兩個引用,記錄次數據前一個數據和后一個數據。(這樣使得使用linkedhashset時,造成添加的先后順序,和打印的先后順序一致,但其實存放的數據還是無序的,只是通過鏈表維護起來了,方便遍歷)
優點,對於頻繁的遍歷,使用linkedhashset,效率要比hashset高