生成equals(),hashCode()等时忽略某些属性

时间:2017-05-20 09:26:32

标签: kotlin

假设我有一个包含三个属性的数据类:

data class Product(
    val id: Int,
    val name: String,
    val manufacturer: String)

如果我理解正确,Kotlin将使用所有三个属性生成equals()hashCode(),如下所示:

override fun equals(other: Any?): Boolean {
    if (this === other) return true
    if (other == null || javaClass != other.javaClass) return false
    val that = other as Product?
    return id == that.id &&
            name == that!!.name &&
            manufacturer == that.manufacturer
}

override fun hashCode(): Int {
    return Objects.hash(id, name, manufacturer)
}

那么如果我不想在idequals()中使用hashCode()该怎么办?有没有办法告诉Kotlin在生成这些函数时忽略某些属性? toString()compareTo()怎么样?

3 个答案:

答案 0 :(得分:3)

对于数据类,使用在主构造函数中声明的所有属性生成这些函数。来自official documentation

  

编译器自动从所有成员派生以下成员   在主构造函数中声明的属性:

     
      
  • equals()/ hashCode()对,
  •   
  • toString()形式"用户(姓名=约翰,年龄= 42)",
  •   
  • componentN()函数对应于中的属性   他们的声明顺序,
  •   
  • copy()函数(见下文)。
  •   

如果您希望不将实施的属性考虑在内,您必须将其移出主要构造函数,或者自己实现这些功能。

有关类似问题的更多讨论here

答案 1 :(得分:1)

对我来说效果很好的解决方案是将元数据与数据分开。 e.g:

data class Entity<out T>(val id: Int, val data: T)
data class Person(val name: String, val manufacturer: String)

用法:

val e1 = Entity(1, Person("Mickey", "Disney"))
val e2 = Entity(2, Person("Mickey", "Disney"))
val e3 = Entity(3, Person("Donald", "Disney"))

e1 == e2
// false

e1.data == e2.data
// true

e2.data == e3.data
// false

答案 2 :(得分:0)

来自文档:

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

您的示例必须如下所示:

data class Product(
    val name: String,
    val manufacturer: String) {
    val id: Int
}

有关详细信息,请查看:https://kotlinlang.org/docs/reference/data-classes.html#properties-declared-in-the-class-body