一、前言
在 java 编程中,我们经常需要在 map 中保存一些“键对应的集合”或“键对应的统计信息”。
传统写法往往繁琐,比如:
map<string, list<string>> map = new hashmap<>();
if (!map.containskey("java")) {
map.put("java", new arraylist<>());
}
map.get("java").add("tom");
是不是有点啰嗦?
从 java 8 开始,我们可以用一行优雅的代码解决:
map.computeifabsent("java", k -> new arraylist<>()).add("tom");
这就是今天的主角 —— computeifabsent()。
二、方法定义
computeifabsent() 是 map 接口的一个默认方法,定义如下:
v computeifabsent(k key, function<? super k, ? extends v> mappingfunction)
方法说明:
| 参数 | 类型 | 含义 |
|---|---|---|
| key | k | 要计算或查找的键 |
| mappingfunction | function<? super k, ? extends v> | 当键不存在时,用于生成新值的函数 |
返回值:
- 如果键已存在,返回原来的值;
- 如果键不存在,则使用
mappingfunction计算出一个新值,并放入map; - 如果函数返回
null,则不会插入任何值。
三、基本使用示例
import java.util.*;
public class computeifabsentdemo {
public static void main(string[] args) {
map<string, list<string>> coursemap = new hashmap<>();
// 当键不存在时,创建新列表
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() 自动处理了键的初始化逻辑,让代码更简洁。
四、常见应用场景
可参考如下题目熟练使用 computeifabsent()
五、与其他方法的区别
| 方法 | 说明 | 使用场景 |
|---|---|---|
| putifabsent(key, value) | 如果 key 不存在,则放入指定的 value | 固定值插入 |
| computeifabsent(key, func) | 如果 key 不存在,使用函数生成 value | 动态计算值 |
| computeifpresent(key, func) | 如果 key 存在,重新计算并更新 value | 修改已有值 |
| compute(key, func) | 无论存在与否,都重新计算 | 全面控制更新逻辑 |
| merge(key, value, remappingfunction) | 合并新旧值 | 统计与聚合 |
六、底层实现源码分析(以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;
- 如果不存在,则调用
mappingfunction.apply(key); - 若返回非空,则插入并返回;
- 否则不插入。
七、注意事项 ⚠️
- 不要让 mappingfunction 产生副作用
map.computeifabsent("x", k -> {
// ❌ 不要在这里修改 map 自身!
map.put("y", "test");
return "value";
});
否则可能引发 concurrentmodificationexception。
- 避免返回 null
如果函数返回 null,则不会插入任何值。
map.computeifabsent("key", k -> null);
// 不会添加任何条目
- 线程安全
- 普通
hashmap不是线程安全的; - 若需并发环境,请使用
concurrenthashmap; concurrenthashmap也支持computeifabsent(),且是线程安全版本。
- 普通
到此这篇关于java computeifabsent()方法使用小结的文章就介绍到这了,更多相关java computeifabsent() 内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论