我正在尝试将此代码从java转换为Kotlin:
Comparator.<Pair<String, Integer>, Integer>comparing(Pair::getSecond)
.reversed()
.thenComparing(Pair::getFirst);
Intellij指出,Pair已被弃用。我正在尝试找到惯用的 kotlin 方法来写出来。然而,Intellij产生这个:
companion object {
private val COUNT_COUNTRY_COMPARATOR = Comparator.comparing { obj: Pair<String?, Int?> -> obj.second }
.reversed()
.thenComparing { obj: Pair<String?, Int?> -> obj.first }
}
这不会编译并显示错误:
Type mismatch.
Required:
TypeVariable(U)!
Found:
Int?
在比较器、弃用的 Pair 和奇怪的转换之间,我想知道是否有更好的方法来用 Kotlin 编写它。
Java-to-Kotlin转换器相当聪明,非常有用,但它远非完美;有时它会生成带有语法错误的代码,偶尔(更糟糕)编译但行为不完全相同的代码。因此,始终值得仔细检查其输出。
在这种情况下,有更简洁和惯用的方式,例如:
compareByDescending<Pair<String, Int>>{ it.second }
.thenBy{ it.first }
这使用顶级函数compareByDescending()和扩展函数thenBy(),两者都采用"选择器"函数。
(我发现lambda版本比函数引用版本更容易阅读,但毫无疑问,后者也是可能的。
因为第二个参数是数字,所以你可以使用简单的否定来反转它的顺序。然后,它将简化为:
compareBy<Pair<String, Int>>({ -it.second }, { it.first })
但是,如果任何一对可以Int.MIN_VALUE
,那将不起作用,因为你不能否定它(或者更确切地说,它是它自己的否定),所以这仍然会先于其他一切。