咱們在工做中時常會用到HashSet
,面試也有時候容易被問到,下面我們就來聊聊HashSet
。
java
public class Test { public static void main(String[] args) { HashSet<String> hashSet = new HashSet<>(); hashSet.add("Java"); hashSet.add("R"); hashSet.add("C"); hashSet.add("C#"); hashSet.add("C#"); hashSet.add("Java"); hashSet.add(null); System.out.println("hashSet的長度:" + hashSet.size()); //第一種遍歷方式 System.out.println("第一種方式遍歷"); Iterator<String> iterator = hashSet.iterator(); while (iterator.hasNext()) { System.out.print(iterator.next()); System.out.print(" "); } System.out.println(""); System.out.println("第二種方式遍歷"); for (String string : hashSet) { System.out.print(string); System.out.print(" "); } }}
輸出面試
hashSet的長度:5第一種方式遍歷C# null Java R C第二種方式遍歷C# null Java R C
從上面的例子能夠得知幾個結果:app
1,不能放入重複的。ide
2,不是按照放入的順序存放的。spa
3,null也能夠存放。3d
HashSet
的類圖code
咱們來看看HashSet
究竟是怎麼玩的orm
從JDK1.2
開始有的HashSet
,實現瞭解耦Set,Cloneable
,Serializable
。對象
Set是個接口,定義了不少方法。blog
Cloneable
能夠對象克隆。
Serializable
能夠序列化與反序列。
繼承了抽象類AbstractSet
AbstractSet
也是Set接口的實現類,主要有如下幾個方法:
AbstractSet
實現了三個方法equals
、hashCode
、removeAll
。而後全部繼承AbstractSet
的子類都不用本身去實現此三個方法。
Set
定義了以下方法:
HashSet
中關鍵的變量和方法:
//定義了一個HashMap類型的變量private transient HashMap<E,Object> map;// Dummy value to associate with an Object in the backing Map//與備份Map中的對象關聯的虛擬值private static final Object PRESENT = new Object();public HashSet() { map = new HashMap<>();}//設置HashSet的容量其實就是設置HashMap的容量public HashSet(int initialCapacity) { map = new HashMap<>(initialCapacity);}//求HashSet的大小就是求HashMappublic int size() { return map.size();}//往HashSet存放數據其實就是往HashMap存放數據//數據做爲key,而後value就是固定Object對象PRESENTpublic boolean add(E e) { return map.put(e, PRESENT)==null;}public Iterator<E> iterator() { return map.keySet().iterator();}public int size() { return map.size();}....//序列化與反序列化private void writeObject(java.io.ObjectOutputStream s){ //...}private void readObject(java.io.ObjectInputStream s){ //...}
能夠看出,HashSet
的操做都是基於HashMap
的操做。
HashSet
的全部操做都是基於HashMap
進行操做,用存放進HashSet
的數據做爲HashMap
的key在使用一個固定Object對象做爲HashMap
的value。