You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala中Java ConcurrentHashMap更新后get返回null问题咨询

ConcurrentHashMap在Scala中get返回null的问题分析与解决

我在Scala(版本2.12.8)中使用Java的ConcurrentHashMap,键类型为Long,值类型为ConcurrentLinkedQueue[Int]。使用computeIfAbsent方法填充映射后,控制台显示映射内容为{1=[2]},但调用get(1)却始终返回null,测试未涉及多线程访问。代码示例如下:

val foo = new ConcurrentHashMap[Long, ConcurrentLinkedQueue[Int]]()

// val initialize = new ConcurrentLinkedQueue[Int]()
// initialize.add(1)
// initialize 

// foo.putIfAbsent(1, initialize)
foo.computeIfAbsent(1, k => new ConcurrentLinkedQueue[Int]()).add(2);

// 查看foo时显示 {1=[2]}
foo 

// 但调用get(1)返回null
foo.get(1)

问题原因

核心问题是Scala字面量的装箱类型不匹配:

  • Java的ConcurrentHashMap键类型为java.lang.Long,调用computeIfAbsent(1, ...)时,Scala的1(Int类型)会被自动转换并装箱为java.lang.Long(因为方法参数要求Long类型),所以映射中实际存储的键是java.lang.Long实例。
  • 调用foo.get(1)时,Scala的1是Int类型,会被装箱为java.lang.Integer,和映射中的java.lang.Long键属于不同类型,哈希值与equals判断都不匹配,因此无法找到对应的值,返回null。
  • 控制台显示{1=[2]}是因为ConcurrentHashMap的toString方法仅打印键的数值,不显示具体类型,造成了视觉误导。

正确的使用方式

确保调用get方法时传入的键类型与映射定义的键类型一致,有两种常见方式:

  • 使用Scala的Long类型字面量(添加L后缀):
foo.get(1L) // 1L会被装箱为java.lang.Long,能正确匹配键
  • 显式将Int转换为Long:
foo.get(1.toLong)

如果不想处理Java/Scala类型交互的问题,也可以改用Scala原生的并发集合scala.collection.concurrent.TrieMap,它的类型系统与Scala更兼容。

内容的提问来源于stack exchange,提问作者idwx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 08:25:17