Java computeIfAbsent()方法使用小結(jié)
一、前言
在 Java 編程中,我們經(jīng)常需要在 Map 中保存一些“鍵對應(yīng)的集合”或“鍵對應(yīng)的統(tǒng)計(jì)信息”。
傳統(tǒng)寫法往往繁瑣,比如:
Map<String, List<String>> map = new HashMap<>();
if (!map.containsKey("Java")) {
map.put("Java", new ArrayList<>());
}
map.get("Java").add("Tom");
是不是有點(diǎn)啰嗦?
從 Java 8 開始,我們可以用一行優(yōu)雅的代碼解決:
map.computeIfAbsent("Java", k -> new ArrayList<>()).add("Tom");
這就是今天的主角 —— computeIfAbsent()。
二、方法定義
computeIfAbsent() 是 Map 接口的一個(gè)默認(rèn)方法,定義如下:
V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)
方法說明:
| 參數(shù) | 類型 | 含義 |
|---|---|---|
| key | K | 要計(jì)算或查找的鍵 |
| mappingFunction | Function<? super K, ? extends V> | 當(dāng)鍵不存在時(shí),用于生成新值的函數(shù) |
返回值:
- 如果鍵已存在,返回原來的值;
- 如果鍵不存在,則使用
mappingFunction計(jì)算出一個(gè)新值,并放入Map; - 如果函數(shù)返回
null,則不會(huì)插入任何值。
三、基本使用示例
import java.util.*;
public class ComputeIfAbsentDemo {
public static void main(String[] args) {
Map<String, List<String>> courseMap = new HashMap<>();
// 當(dāng)鍵不存在時(shí),創(chuàng)建新列表
courseMap.computeIfAbsent("Java", k -> new ArrayList<>()).add("Tom");
courseMap.computeIfAbsent("Java", k -> new ArrayList<>()).add("Alice");
courseMap.computeIfAbsent("Python", k -> new ArrayList<>()).add("Bob");
System.out.println(courseMap);
}
}
輸出:
{Java=[Tom, Alice], Python=[Bob]}
? computeIfAbsent() 自動(dòng)處理了鍵的初始化邏輯,讓代碼更簡潔。
四、常見應(yīng)用場景
可參考如下題目熟練使用 computeIfAbsent()
五、與其他方法的區(qū)別
| 方法 | 說明 | 使用場景 |
|---|---|---|
| putIfAbsent(key, value) | 如果 key 不存在,則放入指定的 value | 固定值插入 |
| computeIfAbsent(key, func) | 如果 key 不存在,使用函數(shù)生成 value | 動(dòng)態(tài)計(jì)算值 |
| computeIfPresent(key, func) | 如果 key 存在,重新計(jì)算并更新 value | 修改已有值 |
| compute(key, func) | 無論存在與否,都重新計(jì)算 | 全面控制更新邏輯 |
| merge(key, value, remappingFunction) | 合并新舊值 | 統(tǒng)計(jì)與聚合 |
六、底層實(shí)現(xiàn)源碼分析(以HashMap為例)
摘自 HashMap.java:
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
Objects.requireNonNull(mappingFunction);
Node<K,V> e;
V v;
if ((e = getNode(hash(key), key)) == null) {
V newValue;
if ((newValue = mappingFunction.apply(key)) != null) {
putVal(hash(key), key, newValue, false, true);
return newValue;
}
} else if ((v = e.value) == null) {
V newValue;
if ((newValue = mappingFunction.apply(key)) != null) {
e.value = newValue;
return newValue;
}
} else {
return v;
}
return null;
}
簡而言之:
- 如果 key 存在,直接返回 value;
- 如果不存在,則調(diào)用
mappingFunction.apply(key); - 若返回非空,則插入并返回;
- 否則不插入。
七、注意事項(xiàng) ??
- 不要讓 mappingFunction 產(chǎn)生副作用
map.computeIfAbsent("x", k -> {
// ? 不要在這里修改 map 自身!
map.put("y", "test");
return "value";
});
否則可能引發(fā) ConcurrentModificationException。
- 避免返回 null
如果函數(shù)返回 null,則不會(huì)插入任何值。
map.computeIfAbsent("key", k -> null);
// 不會(huì)添加任何條目
- 線程安全
- 普通
HashMap不是線程安全的; - 若需并發(fā)環(huán)境,請使用
ConcurrentHashMap; ConcurrentHashMap也支持computeIfAbsent(),且是線程安全版本。
- 普通
到此這篇關(guān)于Java computeIfAbsent()方法使用小結(jié)的文章就介紹到這了,更多相關(guān)Java computeIfAbsent() 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java模擬死鎖發(fā)生之演繹哲學(xué)家進(jìn)餐問題案例詳解
這篇文章主要介紹了Java模擬死鎖發(fā)生之演繹哲學(xué)家進(jìn)餐問題,結(jié)合具體演繹哲學(xué)家進(jìn)餐問題的案例形式詳細(xì)分析了死鎖機(jī)制與原理,需要的朋友可以參考下2019-10-10
劍指Offer之Java算法習(xí)題精講數(shù)組與二叉樹
跟著思路走,之后從簡單題入手,反復(fù)去看,做過之后可能會(huì)忘記,之后再做一次,記不住就反復(fù)做,反復(fù)尋求思路和規(guī)律,慢慢積累就會(huì)發(fā)現(xiàn)質(zhì)的變化2022-03-03
Java驗(yàn)證日期時(shí)間字符串是否合法的三種方式
判斷日期經(jīng)常合法出現(xiàn)在IO場景下,下面將盡量使用簡練的思路和代碼呈現(xiàn)給大伙,這篇文章主要給大家介紹了關(guān)于Java驗(yàn)證日期時(shí)間字符串是否合法的三種方式,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-11-11
SpringBoot開發(fā)案例之打造私有云網(wǎng)盤的實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot開發(fā)案例之打造私有云網(wǎng)盤的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
解決idea check out 切換分支時(shí)找不到需要的分支問題
這篇文章主要介紹了解決idea check out 切換分支時(shí)找不到需要的分支問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02
java中SynchronizedList和Vector的區(qū)別詳解
這篇文章主要介紹了java中SynchronizedList和Vector的區(qū)別詳解,Vector是java.util包中的一個(gè)類。 SynchronizedList是java.util.Collections中的一個(gè)靜態(tài)內(nèi)部類。,需要的朋友可以參考下2019-06-06
Java實(shí)現(xiàn)的數(shù)組去重與排序操作詳解
這篇文章主要介紹了Java實(shí)現(xiàn)的數(shù)組去重與排序操作,結(jié)合實(shí)例形式分析了Java針對數(shù)組去重及排序操作相關(guān)遍歷、排序、判斷等使用技巧與注意事項(xiàng),需要的朋友可以參考下2018-07-07
利用Java實(shí)現(xiàn)Word文檔自動(dòng)編號(hào)提取的方法詳解
文章介紹如何用Java從Word試卷中提取自動(dòng)編號(hào),通過創(chuàng)建NumberingContext類識(shí)別中文、阿拉伯?dāng)?shù)字及字母等不同編號(hào)格式,并實(shí)現(xiàn)getParagraphNumbering方法完成結(jié)構(gòu)化轉(zhuǎn)換,解決了傳統(tǒng)方法無法解析編號(hào)的問題,感興趣的小伙伴可以參考閱讀下2025-09-09

