kotlin - 如果在 Kotlin 中修改了可变集中的元素,则无法删除它

标签 kotlin

我在使用 removeAll() 时遇到问题,无法正确删除某些对象。

data class Dog(var name: String)

val dog1 = Dog(name = "dodo")
val dog2 = Dog(name = "mimi")

val set = mutableSetOf<Dog>()
set.add(dog1)
set.add(dog2)

dog1.name = "dodo2"

val beforeSize = set.size // 2

set.removeAll { true }

val afterSize = set.size  // why it is 1!?, I expect it should be 0

removeAll 没有按我的预期工作。可变集中还有一个元素。有什么想法吗?

最佳答案

Set的Javadoc:

Note: Great care must be exercised if mutable objects are used as set elements. The behavior of a set is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is an element in the set.

通过写作

dog1.name = "dodo2"

您正是这样做的,您以影响 equals 比较的方式更改了对象。具体来说,通过使用构造

set.removeAll { true }

您在 LinkedHashSet 中使用了一个代码路径,该路径访问每个元素,测试其上的谓词,然后尝试通过调用 set.remove(it) 来删除它>。这将导致 it 重新计算其哈希码,现在与您将其插入集合时的哈希码不同。 LinkedHashSet 然后会查找对应的哈希桶,找不到 it 那里。

关于kotlin - 如果在 Kotlin 中修改了可变集中的元素,则无法删除它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49646150/

相关文章:

android - 从 Kotlin RecyclerView(cardview) onclick 加载详细信息 View

unit-testing - 使用 kotlin 协程时,如何对调用挂起函数的函数进行单元测试?

kotlin - 是否有标准的Kotlin函数将Sequence分为头和尾?

kotlin - 在Kotlin中使用Sequence时如何处理掉入过滤器的元素

android - 单击其他 Activity 中的后退按钮时,Firebase Recyclerview(垂直滚动)始终滚动到开始

java - 如果不存在则插入整数,如果 Firebase 实时数据库 Android 中已存在则递增

android - Android Room强制通过自动增量值重写属性

java - 如何将 SSL 证书添加到 okHttp 双向 TLS 连接?

android - android 底部导航栏的 png 图标

java - 如果我们使用基于单一 Activity 的架构,View Model 可能会很重