java-Set-HashSet

特點
實現了Set接口
HashSet依賴的數據結構是HashMap
因爲實現的是Set接口,所以不允許有重複的值
插入到HashSet中的對象不保證與插入的順序保持一致。對象的插入是根據它的hashcode
HashSet中允許有NULL值
HashSet也實現了Searlizable和Cloneable兩個接口

初始化尺寸就是當創建哈希表(HashSet內部用哈希表的數據結構)的時候桶(buckets)的數量。如果當前的尺寸已經滿了,那麼桶的數量會自動增長

裝載因子衡量的是在HashSet自動增長之前允許有多滿。當哈希表中實體的數量已經超出裝載因子與當前容量的積,那麼哈希表就會再次進行哈希(也就是內部數據結構重建),這樣哈希表大致有兩倍桶的數量。

如果內部容量爲16,裝載因子爲0.75,那麼當表中有12個元素的時候,桶的數量就會自動增長。

裝載因子和初始化容量是影響HashSet操作的兩個主要因素。裝載因子爲0.75的時候可以提供關於時間和空間複雜度方面更有效的性能。如果我們加大這個裝載因子,那麼內存的上限就會減小(因爲它減少了內部重建的操作),但是將影響哈希表中的add與查詢的操作。爲了減少再哈希操作,我們應該選擇一個合適的初始化大小。如果初始化容量大於實體的最大數量除以裝載因子,那麼就不會有再哈希的動作發生了。

這個類實現了一個哈希表支持的Set接口實現,實際上是一個HashMap
它不能保證集合的迭代順序,特別不能保證隨着時間的推移,秩序將保持不變。
這個類允許null值

此類爲基本操作提供恆定的時間性能(add、remove、contains、size).
假設hash函數在桶之間正確地分散元素,在這個集合上迭代需要時間,與HashSet實例大小的和加上HashMap實例支持的capacity(bucket桶的數量)成比例。
因此不設置初始容量太高或者load factor太低是非常重要的 如果迭代性能是重要的,如果迭代性能是重要的。

同步
注意此實現不同步,如果多個線程同時訪問哈希集,則至少有一個線程修改集合,它必須外部同步。這通常是通過對某些對象進行同步來實現的。自然封裝該集合。

如果不存在這樣的對象,則應該使用wrapped {@link Collections#synchronizedSet Collections.synchronizedSet}方法。最好在創建時完成,以防止意外發生。

 Set s = Collections.synchronizedSet(new HashSet(...));

迭代器由class的iterator 是fail-fast 如果這個set可修改的 在任何時候 在迭代器創建之後,如果迭代器在任何時候修改了集合,除了通過迭代器自己的remove方法,
迭代器將會拋出{@link ConcurrentModificationException}.
因此,面對併發修改,iterator 快速而乾淨失敗,而不是在未來時間 不確定的 冒險的行爲 。

注意,迭代器的故障快速行爲不能得到保證,事實上,一般來說,不可能作出任何硬的保證,存在不同步的併發修改。故障快速迭代器在盡力的基礎上拋出ConcurrentModificationException、
*因此,編寫一個依賴於此異常正確性的程序是錯誤的。迭代器的fail-fast行爲只用於檢測缺陷。


 /** 
     * 如果此set中尚未包含指定元素,則添加指定元素。 
     * 更確切地講,如果此 set 沒有包含滿足(e==null ? e2==null : e.equals(e2)) 
     * 的元素e2,則向此set 添加指定的元素e。 
     * 如果此set已包含該元素,則該調用不更改set並返回false。 
     * 
     * 底層實際將將該元素作爲key放入HashMap。 
     * 由於HashMap的put()方法添加key-value對時,當新放入HashMap的Entry中key 
     * 與集合中原有Entry的key相同(hashCode()返回值相等,通過equals比較也返回true), 
     * 新添加的Entry的value會將覆蓋原來Entry的value,但key不會有任何改變, 
     * 因此如果向HashSet中添加一個已經存在的元素時,新添加的集合元素將不會被放入HashMap中, 
     * 原來的元素也不會有任何改變,這也就滿足了Set中元素不重複的特性。 
     * @param e 將添加到此set中的元素。 
     * @return 如果此set尚未包含指定元素,則返回true。 
     */ 
 public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
 // 定義一個虛擬的Object對象作爲HashMap的value,將此對象定義爲static final。  
    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章