Kotlin等于和哈希码生成器

时间:2018-05-21 13:06:29

标签: kotlin

我知道在Kotlin类中会有一个自动创建的equals和hashcode,如下所示:

data class CSVColumn(private val index: Int, val value: String) {
}

我的问题是,有没有办法让实现只使用其中一个属性(例如index)而无需自己编写代码。那个非常简洁的课程现在看起来像这样:

data class CSVColumn(private val index: Int, val value: String) {

    override fun equals(other: Any?): Boolean {
        if (this === other) {
            return true
        }
        if (javaClass != other?.javaClass) {
            return false
        }
        other as CSVColumn
        if (index != other.index) {
            return false
        }
        return true
    }

    override fun hashCode(): Int {
        return index
    }

}

在使用Lombok的Java中,我可以执行以下操作:

@Value
@EqualsAndHasCode(of="index")
public class CsvColumn {
    private final int index;
    private final String value;
}

如果有办法告诉Kotlin类似的事情会很酷。

5 个答案:

答案 0 :(得分:3)

对于数据类,您无法执行此类操作,但它们始终以相同的方式生成equalshashCode,无法为其提供此类提示或选项。

但是,它们只包含主要构造函数中的属性,因此您可以为它们执行此操作,使其仅包含index

data class CSVColumn(private val index: Int, value: String) {
    val value: String = value
}

...除了在使用数据类时,主构造函数中的参数不具备属性。

所以你必须以某种方式引入一个带有两个参数的辅助构造函数,如下所示:

class CSVColumn private constructor(private val index: Int) {

    var value: String = ""

    constructor(index: Int, value: String) : this(index) {
        this.value = value
    }

}

...但现在您的value属性必须是var,以便辅助构造函数能够设置其值。

所有这些都表明它可能不值得尝试解决它。如果您需要equalshashCode的非默认实施,数据类无法为您提供帮助,您需要手动实施和维护它们。

编辑:正如@tynn指出的那样,私有的setter可能是一个解决方案,因此你的value在课堂外不可变:

class CSVColumn private constructor(private val index: Int) {

    var value: String = ""
        private set

    constructor(index: Int, value: String) : this(index) {
        this.value = value
    }

}

答案 1 :(得分:1)

Data Classes文档中获取:

  

请注意,编译器仅使用主构造函数中定义的属性来自动生成函数。要从生成的实现中排除属性,请在类主体

中声明它

因此,您必须手动或在 Kotlin编译器插件的帮助下实施equals()hashCode()

答案 2 :(得分:0)

我写了一个叫做“ stem”的小工具,它允许您选择要考虑相等性和散列的属性。生成的代码与手动实现equals()/hashCode()所获得的代码一样小:

class CSVColumn(private val index: Int, val value: String)  {
    private val stem = Stem(this, { index })

    override fun equals(other: Any?) = stem.eq(other)
    override fun hashCode() = stem.hc()
}

您可以看到其实现here

答案 3 :(得分:0)

我想我们现在必须手动编写equals()/hashCode()https://discuss.kotlinlang.org/t/automatically-generate-equals-hashcode-methods/3779

它不受支持,并计划成为恕我直言。

答案 4 :(得分:0)