kotlin - 如何覆盖哈希码

j2e*_*nue 2 equals kotlin

我已经覆盖了 java 对象的 equals 方法。(实际上是 kotlin 中的对象,但它很容易理解,我只是覆盖了 equals 方法)。但现在为了维护 equals 合同,我还应该覆盖 hashcode 方法。但我不知道如何实现适合 equals 方法的哈希码。这是我到目前为止所拥有的:

    data class AddressModel(
        var id_address: Int = 0,
        var id_country: Int = 0,
) {

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other !is AddressModel)
            return false
        else {
            if (other.id_address == this.id_address)
                return true
        }
        return false
    }
}
Run Code Online (Sandbox Code Playgroud)

编译器强烈建议我覆盖 hashCode 方法。但我不明白要实施什么。在 equals 覆盖中,我只想检查 addressModel 是否与另一个具有相同的 Id,如果是,那么我假设它相等。

这是我到目前为止:

override fun hashCode(): Int {
        return Objects.hash(id_address, id_country);
    }
Run Code Online (Sandbox Code Playgroud)

但我认为这更好:

override fun hashCode(): Int {
            return Objects.hash(id_address); //base hash off same as equals the id_address
        }
Run Code Online (Sandbox Code Playgroud)

这是我推荐的阅读方式,但这是什么意思?如果我添加了更多的类字段,我是否还需要向 Objects.hash 方法添加更多的字段?我更喜欢旧的 skool 方式来做到这一点,因为这个调用需要 android api 19 并且我支持较低的(api 16)。

需要明确的是,我明白如果我不覆盖 hashcode 和 equals,那么每个实例,例如“new AddressModel(707, 867)”,都会有一个不同的 hashcode。然后例如 HashMap 会认为这些对象是不同的,并且在计算哈希存储时不等于替换它们。但我只是不知道在 hashCode 实现中放什么。你可以用 kotlin 或 java 给我看,没问题。

更新:这是否足够:

override fun hashCode(): Int { return id_address.hashCode() }
Run Code Online (Sandbox Code Playgroud)

Pra*_*ant 6

因为,您的 #equals() 仅取决于id_address,所以应该在哈希码计算中使用它。我会选择:

override fun hashCode() = Objects.hash(id_address)
Run Code Online (Sandbox Code Playgroud)

  • 请注意,在最新版本的 Kotlin(我认为是 1.3 或更高版本)中,甚至可以在 null 对象上调用 hashCode。有关详细信息,请参阅[此处](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/hash-code.html)。所以在这种情况下,就不需要猫王操作员了。 (2认同)