【问题标题】:Kotlin: generate a Comparable#compareTo() function from the properties of a classKotlin:从类的属性生成 Comparable#compareTo() 函数
【发布时间】:2018-06-04 13:52:52
【问题描述】:

在 Kotlin 中,是否有任何简洁的方法可以为一个接口生成一个 Comparable#compareTo() 函数,该函数只按照声明顺序为接口的每个属性调用 this.property1.compareTo(that.property1)?显然,接口的每个属性都实现了Comparable

对于接口I,看起来我可以创建一个顶级val,如:

private val COMPARATOR = compareBy<I>(
    {it.property1},
    {it.property2},
    {it.property3},
    ...
)

还有来自I#compareTo(I)return COMPARATOR.compare(this, other),但是,有没有更简单的方法可以做到这一点?

【问题讨论】:

  • 我强烈建议完全按照您上面所说的去做,以增加对魔法的明确性。

标签: kotlin compare comparator compareto


【解决方案1】:

您可以像这样使用反射和一些简单的语言功能:

inline fun <reified T : Any> compareByAll(): Comparator<T> {
    val selector = T::class.memberProperties
        .map { { i: T -> it.get(i) as Comparable<*> } }
        .toTypedArray()
    return compareBy(*selector)
}

这样使用:

val testInput = listOf(I(1, 2, 3), I(1, 2, 4), I(1, 0, 4), I(2, 3, 4), I(0, 1, 2)
testInput.sortedWith(compareByAll()))

请注意,此解决方案不处理属性不是Comparable 的情况。

【讨论】:

  • T::class.memberProperties 似乎返回按字母顺序排序的属性。我希望它们按声明顺序排列,以便我可以轻松控制属性比较顺序,因为这会影响返回值。另外,有没有办法将迭代属性限制在主构造函数中,而不是类的所有属性? (我知道我的问题没有问后半部分,但我只是想到了一些我想添加的派生属性,这些属性对于比较来说不是必需的)
猜你喜欢
  • 2021-05-17
  • 1970-01-01
  • 2023-03-21
  • 2011-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多