如何为对象ArrayList生成跨多次执行一致的哈希码?
需求:生成跨执行一致的ArrayList对象哈希码
我尝试从对象ArrayList生成一个多次执行时保持一致的哈希码。之前用ArrayList.hashCode(),但每次返回值都不一样(误以为它基于内存地址生成);试过MD5哈希,但没法转换成字节数组。
希望找到一种可靠且一致的哈希实现,不用迭代提取ArrayList中的字符串。
我的ArrayList结构如下:
[[[ObjectClass1, ObjectClass1], ObjectClass2]] data class class1( val a: String, val b: String, val c: Int, val d: class3, val e: Boolean ) data class class3(val a: Set<String>) enum class class2 { HI, BYE }
当前代码:
class Hasher() { companion object { private lateinit var toBeHashed override fun equals(other: Any?): Boolean { return super.equals(other) } override fun hashCode(): Int { // create hash here toBeHashed.hashCode() } fun createHash(arrayList) { toBeHashed = arrayList val hash = hashCode() return hash } } } Hasher.createHash(arrayList)
解决方案
1. 利用Kotlin数据类特性直接生成一致哈希
首先纠正一个误解:ArrayList.hashCode()不依赖内存地址,它是基于元素内容计算的。而Kotlin的data class默认会根据所有属性生成基于值的hashCode(),Set的标准hashCode()同样基于元素内容。
只要你的自定义类都是data class(你已经满足),直接调用列表的hashCode()就能得到跨执行一致的哈希:
val consistentHash = arrayList.hashCode()
2. 生成加密级哈希(如MD5/SHA)的正确方式
如果需要字符串形式的加密级哈希,可通过序列化对象为字节数组再计算:
步骤1:添加序列化支持
引入Kotlinx Serialization库,给数据类加上@Serializable注解:
import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json @Serializable data class class1( val a: String, val b: String, val c: Int, val d: class3, val e: Boolean ) @Serializable data class class3(val a: Set<String>) @Serializable enum class class2 { HI, BYE }
步骤2:序列化并计算哈希
import java.security.MessageDigest fun generateConsistentHash(list: List<Any>): String { // 序列化为稳定的JSON字符串(按属性定义顺序输出) val json = Json.encodeToString(list) // 转换为字节数组 val bytes = json.toByteArray() // 计算MD5哈希 val md = MessageDigest.getInstance("MD5") val hashBytes = md.digest(bytes) // 转换为十六进制字符串 return hashBytes.joinToString("") { "%02x".format(it) } } // 使用示例 val md5Hash = generateConsistentHash(arrayList)
3. 修复你现有代码的问题
你的Hasher类存在语法错误和设计问题,修复后的极简版本(基于内容哈希):
object Hasher { fun createHash(arrayList: List<Any>): Int { return arrayList.hashCode() } } // 使用 val hash = Hasher.createHash(arrayList)
关键注意点
- 所有自定义类必须正确实现
hashCode():Kotlindata class自动完成,普通类需手动基于属性实现 - 序列化方式要保证输出稳定,Kotlinx Serialization默认按属性定义顺序生成JSON,避免哈希不一致
- 若列表元素包含非
data class的自定义对象,必须手动为其实现基于值的hashCode()和equals()
内容的提问来源于stack exchange,提问作者Abhishek Chandran
相关产品推荐
相关产品推荐

