一、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-hk/n/136711.html