Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Kotlin: Unusual behavior when dealing with sets

I have a simple data class which stores x and y coordinates of a position. My use case is that a single object of this class will be created and updated, and I need to maintain a set of unique coordinates.

I’ve simplified my use case in the following code where adding the pos object directly to the set vs passing the copy of the object result in different behavior (please see the comment in the code).

My initial hunch was that it could be because Java/Kotlin is passing the object by reference and the Set.add compares on reference. However, that doesn’t seem to be true, if I set the pos.x or pos.y to any other value then the set.contains method returns false.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Question:
If the comparison is by reference then why does it fail when setting to a value other than what is given in the below code? If comparison is by hash code then why does the setByCopy not return true in the original case?

data class Pos(var x: Int = 0, var y: Int = 0)

fun main() {
    val pos = Pos(0, 0)
    val set = mutableSetOf<Pos>()
    val setByCopy = mutableSetOf<Pos>()

    pos.x = -9
    pos.y = -6
    set.add(pos)
    setByCopy.add(pos.copy())

    println(pos.hashCode())


    pos.x = -8
    pos.y = -37
    // setting pos.y to any other value (e.g -35) will cause set.contains(pos) to return false.

    println(set.contains(pos))       // true, but expected false.
    println(setByCopy.contains(pos)) // false
}

>Solution :

As usual, modifying an element that’s already in a set produces undefined behavior. This is not explicitly documented in Kotlin, but carries over from Java, where it’s documented:

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.

This means that anything can happen: it can work or not work randomly.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading