Java中HashMap的使用操作
一、概念
HashMap 位于 java.util 包下。它實現(xiàn)了 Map 接口,提供了基于鍵值對(Key-Value)的數(shù)據(jù)存儲方式,并允許使用 null 作為鍵和值。
核心思想:使用“鍵(Key)”的哈希值來存儲和檢索“值(Value)”。
核心特點:
- 基于哈希表:它使用哈希算法來存儲和檢索數(shù)據(jù),這使得在理想情況下,
get和put操作的時間復雜度可以達到 O(1)。 - 無序:
HashMap不保證其中元素的順序(即插入順序和訪問順序),并且順序也可能會隨時間(如擴容時)而變化。如果需要有序,可以使用LinkedHashMap。 - 非線程安全:多個線程同時操作一個
HashMap可能會導致數(shù)據(jù)不一致。如果多個線程同時訪問一個HashMap并至少有一個線程修改了它,則必須在外部進行同步?;蛘呤褂?nbsp;Collections.synchronizedMap()進行包裝,或者更推薦使用ConcurrentHashMap。
二、常用操作
2.1 初始化
// 1. 最常見的無參構造,默認初始容量16,負載因子0.75 HashMap<String, Integer> map = new HashMap<>(); // 2. 指定初始容量(減少擴容次數(shù),優(yōu)化性能) HashMap<String, Integer> mapWithCapacity = new HashMap<>(32); // 3. 指定初始容量和負載因子(高級用法,通常不需要) HashMap<String, Integer> mapWithFactor = new HashMap<>(32, 0.8f); // 4. 通過另一個Map來創(chuàng)建 HashMap<String, Integer> anotherMap = new HashMap<>(map);
擴容機制:擴充為原數(shù)組容量的2倍
當 HashMap 中的元素數(shù)量(size)超過當前閾值(threshold) 時,就會觸發(fā)擴容。
閾值 (threshold) = 容量 (capacity) * 負載因子 (load factor)
- 默認示例:默認容量為 16,默認負載因子為 0.75。
- 那么閾值就是
16 * 0.75 = 12。 - 當執(zhí)行
put()操作后,size變得大于 12(即 13)時,就會觸發(fā)擴容。
- 那么閾值就是
2.2 CRUD
HashMap<String, String> capitalCities = new HashMap<>();
// 添加與更新
// put(K key, V value) - 添加鍵值對,如果key已存在,則更新其value
capitalCities.put("USA", "Washington D.C.");
capitalCities.put("Germany", "Berlin");
capitalCities.put("Germany", "Berlin"); // 重復放入,不會改變
capitalCities.put("Germany", "New Berlin"); // Key已存在,Value會被更新為 "New Berlin"
// putIfAbsent(K key, V value) - (Java 8+) 只有在key不存在或對應的value為null時,才放入
capitalCities.putIfAbsent("France", "Paris"); // 會放入,因為France不存在
capitalCities.putIfAbsent("Germany", "Paris"); // 不會放入,因為Germany已存在,Value仍然是"New Berlin"
// 獲取元素
// get(Object key) - 根據(jù)key獲取value,如果key不存在,返回null
String capitalOfGermany = capitalCities.get("Germany"); // "New Berlin"
String capitalOfJapan = capitalCities.get("Japan"); // null
// getOrDefault(Object key, V defaultValue) - (Java 8+) key不存在時返回一個默認值
String capitalOfJapanSafe = capitalCities.getOrDefault("Japan", "Not Found"); // "Not Found"
// 檢查元素是否存在
// containsKey(Object key) - 檢查某個key是否存在
boolean hasGermany = capitalCities.containsKey("Germany"); // true
boolean hasJapan = capitalCities.containsKey("Japan"); // false
// containsValue(Object value) - 檢查某個value是否存在(效率較低,需要遍歷)
boolean hasParis = capitalCities.containsValue("Paris"); // true
// 刪除元素
// remove(Object key) - 根據(jù)key刪除鍵值對,返回被刪除的value
String removedValue = capitalCities.remove("Germany"); // removedValue = "New Berlin"
// remove(Object key, Object value) - (Java 8+) 只有當key和value都匹配時才刪除
boolean isRemoved = capitalCities.remove("USA", "LA"); // false, 因為Value不匹配"Washington D.C.",刪除失敗
boolean isRemoved2 = capitalCities.remove("USA", "Washington D.C."); // true, 刪除成功2.3 遍歷
// 遍歷所有鍵:keySet()
for (String country : capitalCities.keySet()) {
System.out.println("Country: " + country);
// 可以通過key再get value,但效率較低(不推薦在循環(huán)內這樣用)
// System.out.println("Capital: " + capitalCities.get(country));
}
// 遍歷所有值:values()
for (String capital : capitalCities.values()) {
System.out.println("Capital: " + capital);
}
// 遍歷所有鍵值對:entrySet() (最推薦、最高效的方式)
for (Map.Entry<String, String> entry : capitalCities.entrySet()) {
String country = entry.getKey();
String capital = entry.getValue();
System.out.println(country + " -> " + capital);
}
// 使用 Java 8 forEach + Lambda 表達式 (最簡潔)
capitalCities.forEach((country, capital) -> {
System.out.println(country + " -> " + capital);
});2.4 其他常用方法
// size() - 返回鍵值對的數(shù)量
int size = capitalCities.size();
// isEmpty() - 判斷是否為空
boolean isEmpty = capitalCities.isEmpty();
// clear() - 清空所有映射
capitalCities.clear();
// replace(K key, V oldValue, V newValue) - (Java 8+) 替換操作
capitalCities.replace("France", "Paris", "Lyon"); // 只有當舊值匹配時才替換三、與其他Map的比較
| 特性 | HashMap | LinkedHashMap | TreeMap | Hashtable | ConcurrentHashMap |
|---|---|---|---|---|---|
| 排序保證 | 無順序 | 插入順序 或 訪問順序 (LRU) | 鍵的自然順序 或 自定義比較器順序 | 無順序 | 無順序 |
是否允許 null | 允許 一個 null key 和多個 null value | 允許 一個 null key 和多個 null value | 不允許 null key (取決于Comparator) | 不允許 null key 或 null value | 不允許 null key 或 null value |
| 線程安全 | 否 (非同步) | 否 (非同步) | 否 (非同步) | 是 (同步,每個方法都用 synchronized 修飾) | 是 (采用分段鎖/CAS等更高效的并發(fā)控制) |
| 性能特點 | O(1) 時間復雜度的 get/put (平均情況) | 比 HashMap 稍慢,因為要維護鏈表 | O(log n) 時間復雜度的 get/put | 類似 HashMap,但同步開銷大,性能差 | 高并發(fā)性能極佳,讀操作通常無需鎖 |
| 底層實現(xiàn) | 數(shù)組 + 鏈表/紅黑樹 (哈希表) | HashMap + 雙向鏈表 (維護順序) | 紅黑樹 | 數(shù)組 + 鏈表 (哈希表) | 數(shù)組 + 鏈表/紅黑樹 + CAS + 分段鎖 (JDK 7/8 不同) |
| 迭代順序一致性 | 不保證,甚至可能隨時間變化 | 保證,與插入順序或訪問順序一致 | 保證,根據(jù)鍵的順序排序 | 不保證 | 不保證 |
| 引入版本 | JDK 1.2 | JDK 1.4 | JDK 1.2 | JDK 1.0 (是古老遺留類) | JDK 1.5 (java.util.concurrent 包) |
到此這篇關于Java中HashMap的使用操作的文章就介紹到這了,更多相關Java HashMap內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
spring boot輸入數(shù)據(jù)校驗(validation)的實現(xiàn)過程
web項目中,用戶的輸入總是被假定不安全不正確的,在被處理前需要做校驗。本文介紹在spring boot項目中實現(xiàn)數(shù)據(jù)校驗的過程,通過實例代碼給大家介紹的非常詳細,需要的朋友參考下吧2021-09-09
如何動態(tài)修改JavaBean中注解的參數(shù)值
這篇文章主要介紹了如何動態(tài)修改JavaBean中注解的參數(shù)值操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02
SpringBoot實現(xiàn)簡易支付寶網(wǎng)頁支付功能
小編最近實現(xiàn)一個功能基于springboot程序的支付寶支付demo,非常不錯適合初學者入門學習使用,今天把SpringBoot實現(xiàn)簡易支付寶網(wǎng)頁支付功能的示例代碼分享給大家,感興趣的朋友參考下吧2021-10-10
JAVA基于Arrays.sort()實現(xiàn)數(shù)組升序和降序
這篇文章主要介紹了JAVA基于Arrays.sort()實現(xiàn)數(shù)組升序和降序,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-06-06

