【问题标题】:Kotlin HashSet wrong behaviour (bug)Kotlin HashSet 错误行为(错误)
【发布时间】:2019-06-26 22:16:41
【问题描述】:

HashSet 类有一个奇怪的行为。我不知道为什么,但是方法contains 返回错误的结果。这是来自调试器的图像:

rootElemetns 是一个 HashSet,其中包含一些由简单数据类表示的 FsEntries(没有任何附加方法,只有字段)。如您所见,传递给方法containsfsEntry 与突出显示的元素相同(地址@8939 相同)。

为什么contains 返回false,但indexOf 是5?这是未知的 Kotlin 错误吗?提前致谢。

Kotlin 插件版本:1.3.40

P.S 对于这个 Set 中的其他元素,我得到了正确的结果。

P.P.S.如您所见,如果我通过toArray() 方法转换rootElements 它也会返回正确的结果

【问题讨论】:

  • 您是否在将对象插入 Set 后对其进行更改?你可能弄乱了它存储的哈希值。
  • 你能创建一个minimal reproducible example吗?
  • @Carcigenicate 嗯,可能有一个字段改变了。我明天检查一下。谢谢你的想法。
  • 如果是这种情况,那么您很可能违反了 Set 的要求。在 Java 中,您不能更改 HashMap(HashSet 由其支持)的键。在 Kotlin 中可能类似。当您插入对象时,它会对其进行哈希处理并根据哈希值将其放入插槽中。如果您随后更改对象,则哈希将更改,并且在成员资格测试期间对对象进行哈希时,哈希将不同,并且查找失败。
  • 如果您需要插入的对象是可变的,请考虑改用 HashMap,将对象与某个 ID 键关联,然后查找 ID。值改变也没关系。

标签: android kotlin set hashset


【解决方案1】:

感谢 Carcigenicate,我将给出的答案发布为正确的。

“如果是这种情况,那么您很可能违反了 Set 的要求。在 Java 中,您无法更改 HashMap(HashSet 由其支持)的键。在 Kotlin 中可能类似。当您插入对象,它对它进行哈希处理,然后根据哈希值将其放入一个槽中。如果您随后更改对象,哈希值将更改,并且在成员资格测试期间对对象进行哈希处理时,哈希值将不同,并且查找与失败。”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多