Okay. I'm encountering, of all things, a potential...
# announcements
c
Okay. I'm encountering, of all things, a potential critical bug with
kotlin.collections.ArrayList.indexOf
. I think it's critical, but maybe not. There are fixes but
indexOf
doesn't properly work for me in certain cases ( version 1.3.61) Premise:
val questionsAndAnswers = mutableListOf<Any>()
, in practice containing items of types data class Answer and data class Question. Both have
equals(other: Any)
overriden to return true only when other is of the same type. equals in Answer
Copy code
override fun equals(other: Any?): Boolean {
            return (other as? Answer)?.proof?.sourceNode?.getContentId() == proof?.sourceNode?.getContentId()
}
equals in Question
Copy code
override fun equals(other: Any?): Boolean {
            return (other as? Question)?.item?.getContentId() == item?.getContentId()
}
I do
questionsAndAnswers.indexOf(answer)
knowing my answers are only add odd indexes, and I get a 0. I expected either -1 or odd. Check the debugger, i mapped a bunch of data to help troubleshoot
TL:DR
Copy code
questionsAndAnswers.indexOf(answer) => 0
questionsAndAnswers.indexOfFirst { it == answer } => 1
questionsAndAnswers[0] == answer => false
Also
Copy code
questionsAndAnswers.map { it == answer } =>  size = 3, values are false true false
"false true false" was expected behavior. I instead get false true true as you can see in debugger, even though
questionAndAnswers.map{it.javaClass}
gives me
[Question,Answer,Question]
making the 1st item true impossible. Something is not working right
I can see it being a problem if when you do indexOf interally you first filter by the type that is passed, so indexOf(something at index 1) returns 0 because it is the first item in a list of <ParentType> of that type after filtering
Any nuclear plants using Kotlin? Maybe it's not too late 😢
i
Most likely your
equals
implementation doesn't satisfy one of these contract requirements: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-any/equals.html
For example, if
this.proof
is null, then the Answer would be equal to anything, which is definitely not symmetric.
👆🏻 2
a
specifically, if
other
is a Question, and
this.proof
is null, that equals method will return true (as null is equal to null), which appears to match the screenshotted case
c
You're both right! I'm back a long while later. It was exactly that. I wouldn't have picked up on it being a problem if different equal functions wouldn't return different equals for the same value. I feel like due to the results, it looks like when doing different list functions which compare values of different types o1: A and o2: B, there isn't consistency between which one's equals function is used.
I think it's critical, but maybe not.
My thinking was wrong 😆 big of me to put a bug happening in my code on the language 🤦‍♂️
a
it looks like when doing different list functions which compare values of different types o1: A and o2: B, there isn’t consistency between which one’s equals function is used.
That is exactly correct, which leads to the importance of symmetric equals() implementations. And hence to the difficulty in having data classes extending each other- two siblings in the inheritance tree are unlikely to be able to have symmetric equals() implementations. This issue crops up more with comparator/comparable though in my experience.