HashMap詳解

一、HashMap原理

HashMap是基於哈希表的實現,它是一種將鍵映射到值的數據結構。

HashMap可以通過key來訪問value,因此它提供了非常快速的(近似常數時間)查詢操作。

HashMap採用數組、鏈表、紅黑樹結合的方式實現,數組被分為一個一個的桶,每個桶裡面存放一條鏈表或者紅黑樹,當鏈表長度超過8,並且數組長度大於64時,鏈表就會轉化為紅黑樹,這樣可以提高查詢效率。

二、HashMap和Map區別簡答

Map是所有映射類型的基類,HashMap是Map介面的一種實現。

因此,HashMap繼承了Map介面的所有屬性和行為。在Java中,Map和HashMap都是非常常見的用於存儲鍵值對的容器。

Map是一個映射介面,它提供了每個鍵都可以對應一個值的存儲機制。HashMap是通過繼承AbstractMap來實現的,而且它是一種基於哈希表的Map實現。

三、HashMap方法

HashMap提供了以下方法:

1. put(K key, V value):將指定的值與此映射中的指定鍵相關聯。

2. get(Object key):返回此映射中指定鍵所映射的值。

3. remove(Object key):從此映射中移除指定鍵的映射。

4. containsKey(Object key):如果此映射包含指定鍵的映射,則返回true。

5. containsValue(Object value):如果此映射將一個或多個鍵映射到指定值,則返回true。

6. keySet():返回此映射中包含的鍵的Set視圖。

7. values():返回此映射中包含的值的Collection視圖。

8. entrySet():返回此映射中包含的映射的Set視圖。

四、HashMap的理解

HashMap是一個用於存儲鍵值對的數據結構,它提供了五種不同的存儲方式:數組、鏈表、紅黑樹、欄位元素、桶容量因子。其中,數組、鏈表和紅黑樹的實現來自於Java集合框架的LinkedList和TreeMap類,欄位元素和桶容量因子則是HashMap獨有的特性。

作為HashMap使用者,我們不需要了解HashMap內部的實現原理,只需要了解其提供的方法即可。但是如果想要深入了解Java集合框架,建議可以學習一下HashMap的源碼實現。

五、HashMap的get方法

get方法是HashMap中最常用的方法之一,它用於返回與指定鍵相關聯的值。在HashMap中,get方法可以通過以下步驟來完成:

1. 將key的hashCode作為參數入參傳遞給hash方法。

public V get(Object key) {
    Node e;
    return (e = getNode(hash(key), key)) == null ? null : e.value;
}

2. hash方法會將hashCode的高位異或低位,來保證一個更好的hash值分布,得到對應的桶的索引。

final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

3. 根據桶的索引定位到對應的桶,遍歷桶中的鏈表,如果key相同,則返回對應的value。

final Node getNode(int hash, Object key) {
    Node[] tab;
    Node first, e;
    int n;
    K k;
    if ((tab = table) != null && (n = tab.length) > 0 &&
        (first = tab[(n - 1) & hash]) != null) {
        if (first.hash == hash && // always check first node
            ((k = first.key) == key || (key != null && key.equals(k))))
            return first;
        if ((e = first.next) != null) {
            if (first instanceof TreeNode)
                return ((TreeNode)first).getTreeNode(hash, key);
            do {
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k))))
                    return e;
            } while ((e = e.next) != null);
        }
    }
    return null;
}

六、HashMap用法

HashMap用法非常廣泛,可以通過創建HashMap對象,調用其提供的put方法,向HashMap中添加鍵值對:

HashMap map = new HashMap();
map.put("apple", 1);
map.put("banana", 2);
map.put("orange", 3);

也可以通過get方法,從HashMap中獲取指定鍵對應的值:

Integer value = map.get("apple");

七、HashMap集合說法正確的是

HashMap是一種無序的集合,它不保證集合中元素的順序。

另外,HashMap中可以存儲null值和null鍵。

八、HashMap集

HashMap是一種key-value的數據結構。

它的內部是通過哈希表的方式來存儲數據的。

HashMap中的key和value都可以為null。

當HashMap中出現hash衝突的時候,會採用鏈表的方式來存儲。

九、HashMap擴容

HashMap在存儲元素的時候,存在一個負載因子(load factor)的概念。

當元素的數量達到負載因子與容量的乘積時,HashMap就會自動擴容。默認的負載因子是0.75,即當HashMap的元素數量達到容量的75%時,就會進行擴容。

在擴容的時候,HashMap會將元素重新分配到新的數組中。這個過程需要對每個元素重新計算hash值,因此效率較低。

十、HashMap源碼選取

在HashMap中,我們可以看一下Node類的定義:

static class Node<K,V> implements Map.Entry<K,V> {
    final int hash;
    final K key;
    V value;
    Node<K,V> next;

    Node(int hash, K key, V value, Node<K,V> next) {
        this.hash = hash;
        this.key = key;
        this.value = value;
        this.next = next;
    }

    public final K getKey()        { return key; }
    public final V getValue()      { return value; }
    public final String toString() { return key + "=" + value; }

    public final int hashCode() {
        return Objects.hashCode(key) ^ Objects.hashCode(value);
    }

    public final V setValue(V newValue) {
        V oldValue = value;
        value = newValue;
        return oldValue;
    }

    public final boolean equals(Object o) {
        if (o == this)
            return true;
        if (o instanceof Map.Entry) {
            Map.Entry e = (Map.Entry)o;
            if (Objects.equals(key, e.getKey()) &&
                Objects.equals(value, e.getValue()))
                return true;
        }
        return false;
    }
}

Node類用於存儲鍵值對,也就是哈希表中的元素。它包含了hashCode、key、value、next四個欄位,其中hashCode是計算得到的鍵的哈希值,key和value分別對應鍵和值,next是指向下一個元素的指針。

原創文章,作者:DDXW,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/136711.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
DDXW的頭像DDXW
上一篇 2024-10-04 00:16
下一篇 2024-10-04 00:16

相關推薦

  • Linux sync詳解

    一、sync概述 sync是Linux中一個非常重要的命令,它可以將文件系統緩存中的內容,強制寫入磁碟中。在執行sync之前,所有的文件系統更新將不會立即寫入磁碟,而是先緩存在內存…

    編程 2025-04-25
  • 神經網路代碼詳解

    神經網路作為一種人工智慧技術,被廣泛應用於語音識別、圖像識別、自然語言處理等領域。而神經網路的模型編寫,離不開代碼。本文將從多個方面詳細闡述神經網路模型編寫的代碼技術。 一、神經網…

    編程 2025-04-25
  • Linux修改文件名命令詳解

    在Linux系統中,修改文件名是一個很常見的操作。Linux提供了多種方式來修改文件名,這篇文章將介紹Linux修改文件名的詳細操作。 一、mv命令 mv命令是Linux下的常用命…

    編程 2025-04-25
  • git config user.name的詳解

    一、為什麼要使用git config user.name? git是一個非常流行的分散式版本控制系統,很多程序員都會用到它。在使用git commit提交代碼時,需要記錄commi…

    編程 2025-04-25
  • nginx與apache應用開發詳解

    一、概述 nginx和apache都是常見的web伺服器。nginx是一個高性能的反向代理web伺服器,將負載均衡和緩存集成在了一起,可以動靜分離。apache是一個可擴展的web…

    編程 2025-04-25
  • MPU6050工作原理詳解

    一、什麼是MPU6050 MPU6050是一種六軸慣性感測器,能夠同時測量加速度和角速度。它由三個感測器組成:一個三軸加速度計和一個三軸陀螺儀。這個組合提供了非常精細的姿態解算,其…

    編程 2025-04-25
  • 詳解eclipse設置

    一、安裝與基礎設置 1、下載eclipse並進行安裝。 2、打開eclipse,選擇對應的工作空間路徑。 File -> Switch Workspace -> [選擇…

    編程 2025-04-25
  • Java BigDecimal 精度詳解

    一、基礎概念 Java BigDecimal 是一個用於高精度計算的類。普通的 double 或 float 類型只能精確表示有限的數字,而對於需要高精度計算的場景,BigDeci…

    編程 2025-04-25
  • Python輸入輸出詳解

    一、文件讀寫 Python中文件的讀寫操作是必不可少的基本技能之一。讀寫文件分別使用open()函數中的’r’和’w’參數,讀取文件…

    編程 2025-04-25
  • Python安裝OS庫詳解

    一、OS簡介 OS庫是Python標準庫的一部分,它提供了跨平台的操作系統功能,使得Python可以進行文件操作、進程管理、環境變數讀取等系統級操作。 OS庫中包含了大量的文件和目…

    編程 2025-04-25

發表回復

登錄後才能評論