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

