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

Cod*_*ody 7 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 before_size = set.size // 2

set.removeAll { true }

val after_size = set.size  // why it is 1!?, I expect it should be 0
Run Code Online (Sandbox Code Playgroud)

removeAll没有像我预期的那样工作.可变集中仍然有一个元素.任何的想法?

Mar*_*nik 7

Javadoc Set:

注意:如果将可变对象用作set元素,则必须非常小心.如果在对象是集合中的元素的同时以影响等于比较的方式更改对象的值,则不指定集合的​​行为.

通过写作

dog1.name = "dodo2"
Run Code Online (Sandbox Code Playgroud)

你做到了这一点,你以一种影响equals比较的方式改变了对象.具体而言,通过使用该构造

set.removeAll { true }
Run Code Online (Sandbox Code Playgroud)

你运行了一个代码路径LinkedHashSet,访问每个元素,测试它上面的谓词,然后尝试删除它,就好像通过调用set.remove(it).这将导致it重新计算其哈希码,现在与将其插入集合时的哈希码不同.LinkedHashSet然后会查找相应的哈希桶并找不到it.