簡體   English   中英

Hashmap,Treemap和LinkedHashmap在Java中如何工作?

[英]How do Hashmaps, Treemaps and LinkedHashmaps work in Java?

我對地圖有各種疑問:

  1. 迭代Hashmap時,將無法保證迭代順序。 現在為什么呢?
  2. 為什么Hashmap比Treemap更快?
  3. LinkedHashMaps如何工作,它們如何維護順序? 是因為它們有一個雙向鏈接的列表,其中包含有關在條目之前和之后存儲哪個條目的信息?

我一直在閱讀API文檔,但是由於我是編程的初學者,因此在理解它時有些困難。

迭代Hashmap時,將無法保證迭代順序。 現在為什么呢?

它們的插入順序不是按發生的時間,而是按哈希值插入的值。

例如,假設我們有一個哈希函數h(x) ,它為字符串“ Hello”返回127,為“ Zebra”返回12。 如果我們將這些鍵輸入到哈希映射中,則它們的讀取順序為“ Zebra”->(附加值),然后是“ Hello”->(附加值)。

這在HashMap的源代碼中很明顯:

public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
}

請注意,這是哈希實際執行和代表的簡化版本。 可能是哈希值存在沖突,並且需要以某種方式解決沖突。 這是指底漆; 鍵是按其哈希順序插入的,但是如果您的哈希函數存在缺陷或您對對象的哈希沒有很好的價值,則可能會遇到異常行為。

為什么Hashmap比Treemap更快?

哈希操作不依賴於整個集合的大小。 回想一下, h(x)僅基於我們要插入的單個值進行運算。 如果要在TreeMap插入元素,則必須考慮它們所處的自然順序-這涉及遍歷結構以找到要插入的位置,還可能涉及重新平衡或重新組織結構以確保平衡。保存。

TreeMapput方法的源代碼還有很多

public V put(K key, V value) {
    Entry<K,V> t = root;
    if (t == null) {
        compare(key, key); // type (and possibly null) check

        root = new Entry<>(key, value, null);
        size = 1;
        modCount++;
        return null;
    }
    int cmp;
    Entry<K,V> parent;
    // split comparator and comparable paths
    Comparator<? super K> cpr = comparator;
    if (cpr != null) {
        do {
            parent = t;
            cmp = cpr.compare(key, t.key);
            if (cmp < 0)
                t = t.left;
            else if (cmp > 0)
                t = t.right;
            else
                return t.setValue(value);
        } while (t != null);
    }
    else {
        if (key == null)
            throw new NullPointerException();
        @SuppressWarnings("unchecked")
            Comparable<? super K> k = (Comparable<? super K>) key;
        do {
            parent = t;
            cmp = k.compareTo(t.key);
            if (cmp < 0)
                t = t.left;
            else if (cmp > 0)
                t = t.right;
            else
                return t.setValue(value);
        } while (t != null);
    }
    Entry<K,V> e = new Entry<>(key, value, parent);
    if (cmp < 0)
        parent.left = e;
    else
        parent.right = e;
    fixAfterInsertion(e);
    size++;
    modCount++;
    return null;
}

LinkedHashMaps如何工作,它們如何維護順序? 是因為它們有一個雙向鏈接的列表,其中包含有關在條目之前和之后存儲哪個條目的信息?

您可以自己閱讀源代碼 ,但主要內容如下:

  • 密鑰仍以散列結構分組在一起以確保其唯一性。
  • 它們的插入順序由FIFO結構(如鏈表)保留。

可以這樣想:使用哈希函數確保鍵是唯一的,如果是,則立即將其及其值插入列表中。 這樣,既保留了順序又保留了唯一性。

簡而言之:映射和集合通常是未排序的數據結構。 如果要“排序集”,則最好使用列表或數組。

您的問題更多是關於數據結構的,而不是真正特定的問題或與Java相關的編程問題,因此,您應該從閱讀這些問題開始。 (對不起,作為答復:發表評論需要50次發言)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM