首頁 > 軟體

詳解Java集合類之HashTable,Properties篇

2022-07-27 14:01:08

1.基本介紹

HashTable的鍵和值都不能為空,否則會丟擲一個異常

使用方法基本與HashMap一致

HashTable是執行緒安全的,HashMap是執行緒不安全的

2.HashTable底層

先上程式碼:

Hashtable hashtable = new Hashtable();
hashtable.put("john",100);
hashtable.put("tom",250);
hashtable.put("tom",1314);
System.out.println(hashtable);

輸出:

{tom=1314, john=100}

先進入put方法,可以看到在put方法最前面先判斷了value是否為空,如果為空直接丟擲一個異常

if (value == null) {
    throw new NullPointerException();
}

同樣的,HashTable也存在替換機制和擴容機制!

3.HashTable擴容機制

HashTable擁有自己的擴容機制,這不同於HashSet和HashMap

首先,我們要明白,在HashTable新增鍵值對時,真正起到新增作用的是如下方法:

addEntry(hash, key, value, index);

我們來看一下他的真面目:

private void addEntry(int hash, K key, V value, int index) {
    Entry<?,?> tab[] = table;
    if (count >= threshold) {
        // Rehash the table if the threshold is exceeded
        rehash();

        tab = table;
        hash = key.hashCode();
        index = (hash & 0x7FFFFFFF) % tab.length;
    }

    // Creates the new entry.
    @SuppressWarnings("unchecked")
    Entry<K,V> e = (Entry<K,V>) tab[index];
    tab[index] = new Entry<>(hash, key, value, e);
    count++;
    modCount++;
}

當新增的元素數量大於臨界值時,執行rehash方法(這個方法就是真正的擴容方法)

if (count >= threshold) {
    // Rehash the table if the threshold is exceeded
    rehash();
    tab = table;
    hash = key.hashCode();
    index = (hash & 0x7FFFFFFF) % tab.length;
}

繼續追進去到rehash方法:

protected void rehash() {
    int oldCapacity = table.length;
    Entry<?,?>[] oldMap = table;

    // overflow-conscious code
    int newCapacity = (oldCapacity << 1) + 1;
    if (newCapacity - MAX_ARRAY_SIZE > 0) {
        if (oldCapacity == MAX_ARRAY_SIZE)
            // Keep running with MAX_ARRAY_SIZE buckets
            return;
        newCapacity = MAX_ARRAY_SIZE;
    }
    Entry<?,?>[] newMap = new Entry<?,?>[newCapacity];

    modCount++;
    threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
    table = newMap;

    for (int i = oldCapacity ; i-- > 0 ;) {
        for (Entry<K,V> old = (Entry<K,V>)oldMap[i] ; old != null ; ) {
            Entry<K,V> e = old;
            old = old.next;

            int index = (e.hash & 0x7FFFFFFF) % newCapacity;
            e.next = (Entry<K,V>)newMap[index];
            newMap[index] = e;
        }
    }
}

不要慌,我們來分析一下這個擴容方法

首先,拿到老的容量:

int oldCapacity = table.length;

新的容量為老的容量 * 2 + 1:

int newCapacity = (oldCapacity << 1) + 1;

繼續往下,到達真正擴容的程式碼:

Entry<?,?>[] newMap = new Entry<?,?>[newCapacity];

4.HashMap和HashTable的對比

5.Properties

Properties繼承了HashTable

一般用於可操作的組態檔編寫

使用範例:

import java.util.Properties;

/**
 * Properties演示
 */
public class PropertiesText {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        Properties properties = new Properties();
        // 增加
        properties.put("john",521);
        properties.put("tom",1314);
        properties.put("tom",100);
        System.out.println(properties);
        // 通過key獲取值
        System.out.println(properties.get("tom"));
        // 刪除
        properties.remove("tom");
        System.out.println(properties);
    }
}

輸出:

{tom=100, john=521}
100
{john=521}

6.集合選型規則

儲存一組物件:Collection

允許重複,增刪多選LinkedList,改查多選ArrayList

不允許重複,無序選HashSet,排序選TreeSet,插入和取出順序一致選擇LinkedHashSet

儲存鍵值對:Map

鍵無序:HashMap

鍵排序:TreeMap

鍵插入和取出順序一致:LinkedHashMap

讀取檔案:Properties

到此這篇關於詳解Java集合類之HashTable,Properties篇的文章就介紹到這了,更多相關Java集合類HashTable Properties內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com