分析HashSet中add方法的源碼,保證添加存儲元素的唯一性

class HashSet implements Set {
    private static final Object PRESENT = new Object();
    private transient HashMap<E,Object> map;
    
    public HashSet() {
        map = new HashMap<>();
    }
    
    /**
     * add方法最終調用的是HashMap中的put方法
     * @param e
     * @return
     */
    public boolean add(E e) { //e=hello,world
        return map.put(e, PRESENT)==null;
    }
}

class HashMap implements Map {

    public V put(K key, V value) {
    
        //看哈希表是否爲空,如果空,就開闢空間
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        
        //判斷對象是否爲null
        if (key == null)
            return putForNullKey(value);
        
        //計算key的HashCode值
        int hash = hash(key);
        
        //通過哈希嗎快速找到某個存放位置,這個位置稱爲bucketIndex
        int i = indexFor(hash, table.length);
        
        //判斷
        //* 如果bucketIndex位置沒有元素,在此位置存放鍵值對
        //* 如果bucketIndex位置存在元素,調用equals()判斷對象是否相同,若對象相同,替換原有可value;若不同,即發生碰撞,將新元素存在這個位置,使用單鏈表維護關係
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }
        modCount++;
        //當不同對象hashCode發生碰撞時,HashMap通過單鏈表來解決,將新元素加入鏈表表頭,通過next指向原有的元素
        addEntry(hash, key, value, i);
        return null;
    }
    
    transient int hashSeed = 0;
    
    final int hash(Object k) {
        int h = hashSeed;
        if (0 != h && k instanceof String) {
            return sun.misc.Hashing.stringHash32((String) k);
        }
        h ^= k.hashCode(); //這裏調用的是對象的hashCode()方法
        // This function ensures that hashCodes that differ only by
        // constant multiples at each bit position have a bounded
        // number of collisions (approximately 8 at default load factor).
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章