Kotlin中HashMap以数组为Key时containsKey方法失效,如何修改比较逻辑?
解决Kotlin中数组作为HashMap Key时containsKey不生效的问题
嗨,这个问题我之前也踩过坑!原因其实很简单:Kotlin里的IntArray这类数组是引用类型,HashMap默认是通过对象的引用地址来判断键是否相等的,而不是数组里的元素内容。所以你新创建的intArrayOf(3)和之前存入Map的那个intArrayOf(3)是两个完全不同的对象,引用地址不一样,containsKey自然就识别不出来了。
下面给你两种具体的解决方式,你可以根据场景选择:
方案一:用List代替数组(最简单)
Kotlin的List接口默认实现了基于元素内容的equals和hashCode方法,直接把数组换成List<Int>就能解决问题:
fun main(args: Array<String>) { var map = HashMap<List<Int>, Boolean>() map.put(listOf(1,2,3,4), true) map.put(listOf(2), true) map.put(listOf(3), false) if (map.containsKey(listOf(3))) { println("hello, i'm here") // 现在会正常打印啦 } }
方案二:自定义数组包装类(适合必须用原生数组的场景)
如果你因为性能或者其他原因必须使用IntArray,可以自定义一个包装类,重写equals和hashCode方法,让它基于数组内容来做比较:
// 自定义包装类,基于数组内容判断相等性 class IntArrayKey(val array: IntArray) { override fun equals(other: Any?): Boolean { if (this === other) return true // 引用相同直接返回true if (other == null || javaClass != other.javaClass) return false other as IntArrayKey return array.contentEquals(other.array) // 用数组内容比较 } override fun hashCode(): Int { return array.contentHashCode() // 生成基于数组内容的哈希值 } } fun main(args: Array<String>) { var map = HashMap<IntArrayKey, Boolean>() map.put(IntArrayKey(intArrayOf(1,2,3,4)), true) map.put(IntArrayKey(intArrayOf(2)), true) map.put(IntArrayKey(intArrayOf(3)), false) if (map.containsKey(IntArrayKey(intArrayOf(3)))) { println("hello, i'm here") // 现在可以正常匹配啦 } }
为什么这样可行?
contentEquals方法会逐个比较数组中的元素是否完全一致,而不是比较引用地址;contentHashCode会根据数组的元素内容生成哈希值,确保相同内容的数组有相同的哈希码,这样HashMap才能正确将它们归为同一个键。
内容的提问来源于stack exchange,提问作者Phạm Liêm
相关产品推荐
相关产品推荐

