在不存空值场景下,当前应选用computeIfAbsent还是Kotlin的getOrPut?
Kotlin ConcurrentMap.getOrPut 与 Java computeIfAbsent:何时仍需使用getOrPut?
先明确核心前提:你提到的场景是不打算向Map存入null值,所以getOrPut支持存null的特性可以忽略。接下来分情况讨论:
仍适合用getOrPut的场景
- 默认值计算无副作用且成本极低时:比如只是返回常量(
0、"")、创建空集合(emptyList())这类轻量操作,就算默认函数被多次调用,也不会造成资源浪费或逻辑问题。这时候用getOrPut完全没问题,甚至写法更贴合Kotlin的惯用风格。 - 需要兼容Java 8以下的运行环境:虽然现在Java 8已经是主流,但如果你的项目必须跑在Java 7及更早版本,Java的
computeIfAbsent尚未存在,这时候getOrPut是现成的替代方案。 - 操作非ConcurrentMap的普通Map时:Kotlin的
getOrPut是所有Map接口的扩展函数,而Java的computeIfAbsent是Java 8+才给Map添加的方法。如果是单线程下操作普通HashMap,getOrPut的并发问题不存在,用起来更通用顺手。
优先选computeIfAbsent的场景
- 默认值计算有副作用或成本高昂:比如需要查询数据库、调用远程接口、创建开销大的对象,这时候必须保证默认函数只执行一次——
computeIfAbsent的原子性保证刚好能满足,而getOrPut可能导致重复计算,不仅浪费资源,甚至可能引发数据不一致。 - Java 17+ 环境下的高并发场景:Java 17已经优化了
computeIfAbsent的锁开销,性能和getOrPut持平,但前者有原子性保证,显然是更可靠的选择。
结论
getOrPut绝非遗留API,只是在不存null的高并发Java 17+场景下,computeIfAbsent通常是更优选项。但在轻量无副作用计算、兼容旧环境、普通Map操作这些场景里,getOrPut依然是简洁实用的工具。
内容的提问来源于stack exchange,提问作者k314159
相关产品推荐
相关产品推荐

