java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java computeIfAbsent()

Java computeIfAbsent()方法使用小结

作者: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>当键不存在时,用于生成新值的函数

返回值:

三、基本使用示例

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;
}

简而言之:

七、注意事项 ⚠️

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

您可能感兴趣的文章:
阅读全文