当前位置: 首页 > news >正文

Java computeIfAbsent() 方法详解

请添加图片描述


文章目录

    • 一、前言
    • 二、方法定义
      • 方法说明:
      • 返回值:
    • 三、基本使用示例
    • 四、常见应用场景
    • 五、与其他方法的区别
    • 六、底层实现源码分析(以 `HashMap` 为例)
    • 七、注意事项 ⚠️


一、前言

在 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)

方法说明:

参数类型含义
keyK要计算或查找的键
mappingFunctionFunction<? 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()

49. 字母异位词分组 - 力扣(LeetCode)


五、与其他方法的区别

方法说明使用场景
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)
  • 若返回非空,则插入并返回;
  • 否则不插入。

七、注意事项 ⚠️

  1. 不要让 mappingFunction 产生副作用
map.computeIfAbsent("x", k -> {// ❌ 不要在这里修改 map 自身!map.put("y", "test");return "value";
});

否则可能引发 ConcurrentModificationException

  1. 避免返回 null

如果函数返回 null,则不会插入任何值。

map.computeIfAbsent("key", k -> null);
// 不会添加任何条目
  1. 线程安全
    • 普通 HashMap 不是线程安全的;
    • 若需并发环境,请使用 ConcurrentHashMap
    • ConcurrentHashMap 也支持 computeIfAbsent(),且是线程安全版本。

参考资料

Java HashMap computeIfAbsent() 方法 | 菜鸟教程

http://www.dtcms.com/a/585889.html

相关文章:

  • 做网站市场报价免费企业网站开源系统
  • 天元建设集团有限公司企业代码东莞做网站seo
  • Web前端摄像头调用安全性分析
  • 绵阳网站建设怎么做免费查公司
  • std之list
  • 前端:前端/浏览器 可以录屏吗 / 实践 / 录制 Microsoft Edge 标签页、应用窗口、整个屏幕
  • 做网站像美团一样多少钱中国最新军事消息
  • 软件项目管理实验报告(黑龙江大学)
  • 网络建设需求台州做网站优化
  • PostgreSQL一些概念特性
  • 宁夏建设厅网站6青岛网站建设公司好找吗
  • 社交营销可以用于网站制作行业吗怎样做建网站做淘客
  • 玩转Rust高级应用 如何让让运算符支持自定义类型,通过运算符重载的方式是针对自定义类型吗?
  • 基于Keras的MNIST手写数字识别卷积神经网络设计与实现
  • 百度资料怎么做网站型云网站建设
  • IP配置的基本要求
  • 单母线接线典型操作顺序
  • LightGBM三部曲:LightGBM原理
  • 【C++】C++中的文件IO
  • wordpress手机站如何做负面口碑营销案例
  • 谷歌黑客语法挖掘 SQL 注入漏洞
  • ps做网站logo青海做网站多少钱
  • Qt开发——环境搭建
  • 32HAL——RTC时钟
  • C#知识补充(一)——ref和out、成员属性、万物之父和装箱拆箱、抽象类和抽象方法、接口
  • 专业的设计网站建设网站做地区定位跳转
  • 网站做三层结构南京建设网站哪家好
  • pyautocad 获取选择线段的近似最小包围盒 (OBB) 三分搜索
  • Git Commit 高频提示详解:用户名邮箱配置及其他常见提示解决方案
  • 打开网站图片弹入指定位置代码网络域名备案查询