HashTable —— 安全執行緒的散列表,hashtable線程

來源:互聯網
上載者:User

HashTable —— 安全執行緒的散列表,hashtable線程

HashTable 的一些認識:

■ 重要全域變數

//The hash table data.//底層維護一個Entry(索引值對)數組private transient Entry<K,V>[] table;
//The total number of entries in the hash table.//元素總量,等同於HashMap的sizeprivate transient int count;
//The load factor for the hashtable.//負載因子private float loadFactor;
/** * The table is rehashed when its size exceeds this threshold. * (The value of this field is (int)(capacity * loadFactor).) * 超過閾值進行rehash */private int threshold;/** * The number of times this Hashtable has been structurally modified * Structural modifications are those that change the number of entries in * the Hashtable or otherwise modify its internal structure (e.g., * rehash). This field is used to make iterators on Collection-views of * the Hashtable fail-fast. (See ConcurrentModificationException). * 結構性變動時modCount計數+1,用於遍曆時的fail-fast機制生效 */private transient int modCount = 0

 

■ 建構函式

/**     * Constructs a new, empty hashtable with the specified initial     * capacity and the specified load factor.     */    public Hashtable(int initialCapacity, float loadFactor) {        if (initialCapacity < 0)            throw new IllegalArgumentException("Illegal Capacity: "+                                               initialCapacity);        if (loadFactor <= 0 || Float.isNaN(loadFactor))            throw new IllegalArgumentException("Illegal Load: "+loadFactor);        if (initialCapacity==0)            initialCapacity = 1;    //沒有強調2次冪,cap為0時,預設是1        this.loadFactor = loadFactor;        table = new Entry<?,?>[initialCapacity];        threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);    }       /**     * Constructs a new, empty hashtable with a default initial capacity (11)     * and load factor (0.75).     * 容量11,負載因子 0.75     */    public Hashtable() {        this(11, 0.75f);    }    

 

■主要方法

   - put(K key, V value)

public synchronized V put(K key, V value) {    // Make sure the value is not null,而HashMap選擇將key為null永遠存放為table[0]位置    if (value == null) {        throw new NullPointerException();    }    // Makes sure the key is not already in the hashtable.    //確保key不在hashtable中    //首先,通過hash方法計算key的雜湊值,並計算得出index值,確定其在table[]中的位置    //其次,迭代index索引位置的鏈表,如果該位置處的鏈表存在相同的key,則替換value,返回舊的value    Entry tab[] = table;    int hash = hash(key);    //計算下標,這裡使用%方法,效能遠不及HashMap的位元運算 (這也是不推薦使用HashTable的原因之一)    int index = (hash & 0x7FFFFFFF) % tab.length;    for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {        //直接使用equals比較,而HashMap多了一層地址比較 `((k = e.key) == key || key.equals(k))`        if ((e.hash == hash) && e.key.equals(key)) {            V old = e.value;            e.value = value;            return old;        }    }
//結構性變更操作 modCount計數+1 modCount++; //HashMap選擇新增addEntry方法封裝一下邏輯 if (count >= threshold) { // Rehash the table if the threshold is exceeded //如果超過閥值,就進行rehash操作 rehash(); tab = table; hash = hash(key); index = (hash & 0x7FFFFFFF) % tab.length; } // Creates the new entry. //將值插入,返回的為null Entry<K,V> e = tab[index]; // 建立新的Entry節點,並將新的Entry插入Hashtable的index位置,並設定e為新的Entry的下一個元素 tab[index] = new Entry<>(hash, key, value, e); //size++ count++; return null;}

- get(Object key)

public synchronized V get(Object key) {        Entry tab[] = table;   //臨時拷貝,保證資料的時效性        int hash = hash(key);        int index = (hash & 0x7FFFFFFF) % tab.length;        for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {            if ((e.hash == hash) && e.key.equals(key)) {                return e.value;            }        }        return null;    }

 ■ HashTable 遍曆

/** * Created by roman on 2017/10/03. *【2017 java's day】 */public class ListHashTableTest {    public static void main(String[] args) {        Hashtable<String, Object> hb = new Hashtable<String, Object>();        hb.put("1", "Java");        hb.put("flag", true);        hb.put("age", 44);        Iterator iterator = hb.keySet().iterator();        iterator.forEachRemaining(value -> System.out.println(hb.get(value)));  //使用了lamda    }}

 

■ HashTable VS HashMap

  • HashTable 基於 Dictionary 類,而 HashMap 是基於 AbstractMap。Dictionary 是任何可將鍵映射到相應值的類的抽象父類,而 AbstractMap 是基於 Map 介面的實現,它以最大限度地減少實現此介面所需的工作.
  • HashMap 的 key 和 value 都允許為 null,而 Hashtable 的 key 和 value 都不允許為 null。HashMap 遇到 key 為 null 的時候,調用 putForNullKey 方法進行處理(統一放入table[0]位置),而對 value 沒有處理;Hashtable遇到 null,直接返回 NullPointerException.
  • Hashtable 方法是同步,而HashMap則不是。Hashtable 中的幾乎所有的 public 的方法都是 synchronized 的,而有些方法也是在內部通過 synchronized 代碼塊來實現。
  • HashTable由於使用sync和%運算(以及相關演算法實現)的緣故,相比於HashMap,效能較低,因此非常不推薦繼續使用HashTable。
  • 非競爭環境下推薦使用HashMap。
  • 多線程環境下推薦使用ConcurrentHashMap。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.