Java computeIfAbsent()方法使用小结

 更新时间:2025年12月04日 11:11:13   作者:Geoking.  
本文主要介绍了Java computeIfAbsent()方法使用小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、前言

在 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 computeIfAbsent()方法使用小结的文章就介绍到这了,更多相关Java computeIfAbsent() 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java模拟死锁发生之演绎哲学家进餐问题案例详解

    Java模拟死锁发生之演绎哲学家进餐问题案例详解

    这篇文章主要介绍了Java模拟死锁发生之演绎哲学家进餐问题,结合具体演绎哲学家进餐问题的案例形式详细分析了死锁机制与原理,需要的朋友可以参考下
    2019-10-10
  • MyBatis的模糊查询mapper.xml的写法讲解

    MyBatis的模糊查询mapper.xml的写法讲解

    这篇文章主要介绍了MyBatis的模糊查询mapper.xml的写法讲解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • 剑指Offer之Java算法习题精讲数组与二叉树

    剑指Offer之Java算法习题精讲数组与二叉树

    跟着思路走,之后从简单题入手,反复去看,做过之后可能会忘记,之后再做一次,记不住就反复做,反复寻求思路和规律,慢慢积累就会发现质的变化
    2022-03-03
  • java使用正则抓取网页邮箱

    java使用正则抓取网页邮箱

    这篇文章主要为大家详细介绍了java使用正则抓取网页邮箱的相关资料,感兴趣的小伙伴们可以参考一下
    2016-05-05
  • Java验证日期时间字符串是否合法的三种方式

    Java验证日期时间字符串是否合法的三种方式

    判断日期经常合法出现在IO场景下,下面将尽量使用简练的思路和代码呈现给大伙,这篇文章主要给大家介绍了关于Java验证日期时间字符串是否合法的三种方式,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-11-11
  • SpringBoot开发案例之打造私有云网盘的实现

    SpringBoot开发案例之打造私有云网盘的实现

    这篇文章主要介绍了SpringBoot开发案例之打造私有云网盘的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • 解决idea check out 切换分支时找不到需要的分支问题

    解决idea check out 切换分支时找不到需要的分支问题

    这篇文章主要介绍了解决idea check out 切换分支时找不到需要的分支问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • java中SynchronizedList和Vector的区别详解

    java中SynchronizedList和Vector的区别详解

    这篇文章主要介绍了java中SynchronizedList和Vector的区别详解,Vector是java.util包中的一个类。 SynchronizedList是java.util.Collections中的一个静态内部类。,需要的朋友可以参考下
    2019-06-06
  • Java实现的数组去重与排序操作详解

    Java实现的数组去重与排序操作详解

    这篇文章主要介绍了Java实现的数组去重与排序操作,结合实例形式分析了Java针对数组去重及排序操作相关遍历、排序、判断等使用技巧与注意事项,需要的朋友可以参考下
    2018-07-07
  • 利用Java实现Word文档自动编号提取的方法详解

    利用Java实现Word文档自动编号提取的方法详解

    文章介绍如何用Java从Word试卷中提取自动编号,通过创建NumberingContext类识别中文、阿拉伯数字及字母等不同编号格式,并实现getParagraphNumbering方法完成结构化转换,解决了传统方法无法解析编号的问题,感兴趣的小伙伴可以参考阅读下
    2025-09-09

最新评论