I have an issue when using removeAll()
, some objects can't be removed properly.
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
The removeAll
didn't work as I expected. There is still one element in the mutable set. Any idea?
Javadoc of Set
:
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.
By writing
dog1.name = "dodo2"
you did exactly that, you changed the object in a way that affects equals
comparisons. Specifically, by using the construct
set.removeAll { true }
you exercised a code path in LinkedHashSet
that visits each element, tests the predicate on it, and then tries to remove it as if by calling set.remove(it)
. This will cause it
to recalculate its hash code, now different from what it was when you inserted it into the set. LinkedHashSet
will then look up the corresponding hash bucket and fail to find it
there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With