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

Kotlin中为何equals返回true,LinkedHashMap却找不到对应值?

问题:URI equals返回true但Map无法找到对应值

我有一个映射:

private val secondaryOutputProperties = mutableMapOf<URI, MutableMap<QName, XdmValue>>()

还有一个来自另一映射键的uri: URI对象。执行以下代码时出现无法解释的空指针异常:

for ((puri, _) in secondaryOutputProperties) {
    println("Map URI: $puri, ${puri.equals(uri)}")
}
println("Key URI: $uri")
val x = secondaryOutputProperties[uri]
println("s[uri] = ${x}")
val y = secondaryOutputProperties.get(uri)
println("s.get(uri) = ${y}")
println("in? ${uri in secondaryOutputProperties}")
println("conains? ${secondaryOutputProperties.containsKey(uri)}")

输出结果:

Map URI: file:/Volumes/Projects/xproc/test-suite/test-suite/tests/secondary-false, true
Map URI: file:/Volumes/Projects/xproc/test-suite/test-suite/tests/secondary-true, false
Key URI: file:/Volumes/Projects/xproc/test-suite/test-suite/tests/secondary-false
s[uri] = null
s.get(uri) = null
in? false
conains? false

执行val serprops = secondaryOutputProperties[uri]!!触发NPE,程序为单线程,无其他线程修改映射。为什么puri.equals(uri)返回true,但get()方法找不到对应值?


原因分析

这是因为Java/Kotlin默认的Map实现(比如mutableMapOf创建的HashMap)依赖**equals()和hashCode()方法的一致性约定**:如果两个对象equals()返回true,它们的hashCode()必须返回相同的值。你的场景就是这两个方法违反了这个约定。

具体来说:

  • HashMap查找键时,先通过hashCode()定位对应的哈希桶,再在桶内用equals()比较对象。如果两个对象equals()为true但hashCode()不同,HashMap会认为这是两个不同的键,自然找不到对应值。
  • 大概率是你使用的URI对象(比如自定义实现类,或存在特殊属性的标准URI)没有遵循这个约定:要么equals()逻辑没有覆盖所有影响哈希的属性,要么hashCode()没有基于equals()中比较的属性计算。

验证方法

在打印代码中添加哈希值输出,确认两个URI的哈希值是否不同:

for ((puri, _) in secondaryOutputProperties) {
    println("Map URI: $puri, equals: ${puri.equals(uri)}, hashCode: ${puri.hashCode()}")
}
println("Key URI: $uri, hashCode: ${uri.hashCode()}")

如果输出的哈希值不一致,就坐实了这个问题。

解决方案

  1. 使用标准java.net.URI类:标准URI已经正确重写了equals()和hashCode(),只要两个URI的协议、主机、路径等核心属性一致,这两个方法的结果会保持统一。
  2. 修复自定义URI类:如果是自定义的URI实现,必须基于equals()中比较的所有属性来重写hashCode(),确保equals()为true时哈希值相同。
  3. 临时替换Map实现:如果无法修改URI类,可以改用TreeMap,它依赖compareTo()(或自定义Comparator)而非hashCode(),但TreeMap的查找性能低于HashMap,仅适合小数据量场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 12:25:09