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() 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • kotlin中const 和val的区别及使用场景分析

    kotlin中const 和val的区别及使用场景分析

    在 Kotlin 中,const 和 val 都是用来声明常量的,但它们的使用场景和功能有所不同,下面给大家介绍kotlin中const 和val的区别,感兴趣的朋友一起看看吧
    2025-04-04
  • Springboot中yml文件不生效原因分析及解决

    Springboot中yml文件不生效原因分析及解决

    这篇文章给大家介绍了Springboot中yml文件不生效原因分析及解决方法,通过图文给大家讲解的非常详细,对大家解决问题有一定的帮助,需要的朋友可以参考下
    2024-02-02
  • JAVA 十六进制与字符串的转换

    JAVA 十六进制与字符串的转换

    笔者前几日在开服过程中需要将字符串转化成为16进制的字符串,在网上找到了一些方法尝试之后,均发现存在一个问题-->字符串转为16进制后再转回来,英文正常,中文出现乱码
    2009-05-05
  • SpringBoot如何实现接口版本控制

    SpringBoot如何实现接口版本控制

    这篇文章主要介绍了SpringBoot如何实现接口版本控制,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • Java中正则表达式 .* 的含义讲解

    Java中正则表达式 .* 的含义讲解

    这篇文章主要介绍了Java中正则表达式 .* 的含义,通过举例说明了正则表达式*,+,?的区别,本文给大家讲解的非常详细,需要的朋友可以参考下
    2023-05-05
  • java org.springframework.boot 对redis操作方法

    java org.springframework.boot 对redis操作方法

    在Spring Boot项目中操作Redis,你可以使用Spring Data Redis,Spring Data Redis是Spring提供的一个用于简化Redis数据访问的模块,它提供了一个易于使用的编程模型来与Redis交互,本文给大家介绍java org.springframework.boot 对redis操作方法,感兴趣的朋友一起看看吧
    2025-04-04
  • Java详解数据类型的定义与使用

    Java详解数据类型的定义与使用

    Java 是一种类型安全语言,编译器存储在变量中的数值具有适当的数据类型。学习任何一种编程语言都要了解其数据类型,本文将详细介绍 Java 中的数据类型
    2022-04-04
  • Java利用条件运算符的嵌套来完成学习成绩的划分

    Java利用条件运算符的嵌套来完成学习成绩的划分

    这篇文章主要介绍了Java利用条件运算符的嵌套来完成学习成绩的划分,需要的朋友可以参考下
    2017-02-02
  • mybatis plus框架@TableField注解不生效问题及解决方案

    mybatis plus框架@TableField注解不生效问题及解决方案

    最近遇到一个mybatis plus的问题,@TableField注解不生效,导致查出来的字段反序列化后为空,今天通过本文给大家介绍下mybatis plus框架的@TableField注解不生效问题总结,需要的朋友可以参考下
    2022-03-03
  • spring-integration连接MQTT全过程

    spring-integration连接MQTT全过程

    这篇文章主要介绍了spring-integration连接MQTT全过程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03

最新评论