1. 程式人生 > >常用集合之HashSet原始碼淺析

常用集合之HashSet原始碼淺析

類圖

原始碼

構造方法

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable
{
    //儲存資料的物件,由此就可以看書HashSet是HashMap來實現的
    private transient HashMap<E,Object> map;
    //是所有寫入 map 的 value 值。
    private static final Object PRESENT = new
Object(); public HashSet() { map = new HashMap<>(); } public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } public HashSet(int initialCapacity) { map = new HashMap<>(initialCapacity); } public
Iterator<E> iterator() { return map.keySet().iterator(); } public int size() { return map.size(); } //PRESENT是所有寫入 map 的 value 值。 public boolean add(E e) { return map.put(e, PRESENT)==null; } public boolean remove(Object o) { return map.remove(o)==PRESENT; } //...
}

偷偷告訴你,HashSet中沒有 get 方法。

比較關鍵的就是這個add()方法。 可以看出它是將存放的物件當做了 HashMap 的健,value都是相同的 PRESENT 。由於 HashMapkey 是不能重複的,所以每當有重複的值寫入到HashSet時,value會被覆蓋,但 key不會受到影響,這樣就保證了HashSet中只能存放不重複的元素。

這裡又要多問一句了,為什麼HashMap的鍵值是不重複的呢?因為在HashMap的原始碼中,是使用keyhashCodekey值去 取值的,hashCode總不能重複吧。這就有源有頭了!

    public V get(Object key) {
        Node<K,V> e;
        return (e = getNode(hash(key), key)) == null ? null : e.value;
    }

    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

ps: 文末推薦其他幾篇有關集合的文章: