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