You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为对象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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 19:08:16