深刻源碼探討HashSet

咱們在工做中時常會用到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

5e55ee5f29439b2aff7bbc008e4dfac0.png

咱們來看看HashSet究竟是怎麼玩的orm

515d2095eac382c2f110a43c3a39cdd0.png

JDK1.2開始有的HashSet,實現瞭解耦Set,CloneableSerializable對象

  1. Set是個接口,定義了不少方法。blog

  2. Cloneable能夠對象克隆。

  3. Serializable能夠序列化與反序列。

  4. 繼承了抽象類AbstractSet

AbstractSet也是Set接口的實現類,主要有如下幾個方法:

1e5b94212a7d4d3fe9dc48902ec10b9f.png

AbstractSet實現了三個方法equalshashCoderemoveAll。而後全部繼承AbstractSet的子類都不用本身去實現此三個方法。

Set定義了以下方法:

66d81ab3ca45a2f7c6ebeb317244f4f6.png

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。

相關文章
相關標籤/搜索