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

为何Kotlin代码最后一行输出false?data class与class差异解析

问题原因解释

核心前提

HashSet 判断元素是否存在的逻辑是:先通过元素的 hashCode() 找到对应的哈希桶,再在桶内用 equals() 方法匹配元素。而 Kotlin 的 data class 和普通 class 在 equals()、hashCode() 的实现上有本质差异,这是导致结果不同的关键。


一、Data Class 输出 false 的原因

  1. Data Class 的默认行为:Kotlin 的 data class 会自动基于所有声明的属性(这里是 name 和 surName)生成 equals() 和 hashCode() 方法。也就是说,两个 Person 对象是否相等、hashCode() 的计算值,完全由这两个属性的取值决定。
  2. 执行过程拆解:
    • 初始化 person(name="AA")并加入 HashSet 时,HashSet 会根据此时的 hashCode()(基于AA+BB计算)把对象放到对应的哈希桶里。
    • 修改 person.name = "TEST" 后,该对象的 hashCode() 会基于新的属性值重新计算,发生了变化,但 HashSet 不会自动更新对象在内部哈希桶中的位置。
    • 调用 person in names 时,HashSet 会用当前的 hashCode() 找新的哈希桶,这个桶里没有目标对象;而原来存放该对象的旧哈希桶,HashSet 不会去遍历查找,最终返回 false。

二、普通 Class 输出 true 的原因

  1. 普通 Class 的默认行为:普通 class 没有重写 equals() 和 hashCode(),直接继承自 Object 类的实现:
    • equals() 判断的是对象引用是否相同(等价于 Kotlin 中的 ===),和属性值无关。
    • hashCode() 返回的是基于对象内存地址的固定值,不会因为属性修改而变化。
  2. 执行过程拆解:
    • 即使修改了 person.name,person 的对象引用没有变,hashCode() 值也保持不变。
    • 调用 person in names 时,HashSet 通过原来的 hashCode() 找到对应的哈希桶,然后用 equals() 比较引用,发现集合里的元素就是当前的 person 对象,所以返回 true。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:37:22