MapのKeyって文字列とか数値とかしか使ってなかったけど他のdata classとか使いたいなとなったので調べた。
確かめる
何も考えずdata classを使う
ちゃんと直感的に動く
data class MapKey(val key1: Int, val key2: Int) fun main(args : Array<String>) { // {MapKey(key1=1, key2=0)=0, MapKey(key1=0, key2=0)=1} println(mapOf(MapKey(1, 0) to 0, MapKey(0, 0) to 1)) // {MapKey(key1=0, key2=0)=1} println(mapOf(MapKey(0, 0) to 0, MapKey(0, 0) to 1))
equalsで計算しているのかな
違うっぽい
data class MapKey(val key1: Int, val key2: Int) { override fun equals(other : Any?) : Boolean { return true } } fun main(args : Array<String>) { // {MapKey(key1=1, key2=0)=0, MapKey(key1=0, key2=0)=1} println(mapOf(MapKey(1, 0) to 0, MapKey(0, 0) to 1)) // {MapKey(key1=0, key2=0)=1} println(mapOf(MapKey(0, 0) to 0, MapKey(0, 0) to 1)) }
hashでは
違うんか
data class MapKey(val key1: Int, val key2: Int) { override fun hashCode(): Int { println("hashCode") return 0 } } fun main(args : Array<String>) { // {MapKey(key1=1, key2=0)=0, MapKey(key1=0, key2=0)=1} println(mapOf(MapKey(1, 0) to 0, MapKey(0, 0) to 1)) // {MapKey(key1=0, key2=0)=1} println(mapOf(MapKey(0, 0) to 0, MapKey(0, 0) to 1)) }
両方か
data class MapKey(val key1: Int, val key2: Int) { override fun equals(other : Any?) : Boolean { println("equals") return true } override fun hashCode(): Int { println("hashCode") return 0 } } fun main(args: Array<String>) { println(mapOf(MapKey(1, 0) to 0, MapKey(0, 0) to 1)) println(mapOf(MapKey(0, 0) to 0, MapKey(0, 0) to 1)) }
hashCode hashCode equals {MapKey(key1=1, key2=0)=1} hashCode hashCode equals {MapKey(key1=0, key2=0)=1}
結論
hashCodeが衝突したらequalsを見ている。
P.S.
確かに毎回equalsを見るよりもhashを見たほうが早い。でも衝突する恐れがあるので衝突した場合はequalsを見るのは納得