假设我只想在生成的equals和hashCode实现中包含一个或两个字段(或者可能排除一个或多个字段).对于一个简单的类,例如:
data class Person(val id: String, val name: String)
Run Code Online (Sandbox Code Playgroud)
Groovy有这个:
@EqualsAndHashCode(includes = 'id')
Run Code Online (Sandbox Code Playgroud)
龙目岛有这个:
@EqualsAndHashCode(of = "id")
Run Code Online (Sandbox Code Playgroud)
在Kotlin这样做的惯用方法是什么?
data class Person(val id: String) {
// at least we can guarantee it is present at access time
var name: String by Delegates.notNull()
constructor(id: String, name: String): this(id) {
this.name = name
}
}
Run Code Online (Sandbox Code Playgroud)
虽然感觉不对......我真的不想name变成可变的,额外的构造函数定义很难看.
Dun*_*gor 12
我用过这种方法.
data class Person(val id: String, val name: String) {
override fun equals(other: Person) = EssentialData(this) == EssentialData(other)
override fun hashCode() = EssentialData(this).hashCode()
override fun toString() = EssentialData(this).toString().replaceFirst("EssentialData", "Person")
}
private data class EssentialData(val id: String) {
constructor(person: Person) : this(id = person.id)
}
Run Code Online (Sandbox Code Playgroud)
Nil*_*mat 11
这建立在 @bashor 的方法之上,并使用私有主构造函数和公共辅助构造函数。遗憾的是,equals 要忽略的属性不能是 val,但可以隐藏 setter,因此从外部角度来看结果是等效的。
data class ExampleDataClass private constructor(val important: String) {
var notSoImportant: String = ""
private set
constructor(important: String, notSoImportant: String) : this(important) {
this.notSoImportant = notSoImportant
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这个解决方案不再有效,而且我还没有(这个)这个问题的另一个好主意.
自动生成的函数仅使用在主构造函数中声明的属性(带val或的参数var).所以你可以写:
data class Person(val id: String, name: String) {
val name: String = name
}
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅有关数据类的参考.
这种方法可能适用于财产排除:
class SkipProperty<T>(val property: T) {
override fun equals(other: Any?) = true
override fun hashCode() = 0
}
Run Code Online (Sandbox Code Playgroud)
SkipProperty.equals简单地返回true,这会导致嵌入property被跳过equals父对象。
data class Person(
val id: String,
val name: SkipProperty<String>
)
Run Code Online (Sandbox Code Playgroud)
我也不知道Kotlin(1.1)中的“惯性方式”会执行此操作...
我结束了覆盖equals和hashCode:
data class Person(val id: String,
val name: String) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other?.javaClass != javaClass) return false
other as Person
if (id != other.id) return false
return true
}
override fun hashCode(): Int {
return id.hashCode()
}
}
Run Code Online (Sandbox Code Playgroud)
有没有“更好”的方式?
| 归档时间: |
|
| 查看次数: |
6767 次 |
| 最近记录: |