在Kotlin中将比较器转换为lambda

Jue*_*ang 6 lambda kotlin

我的Kotlin代码中有一个代码片段:

val dataMap = sensoryDataUsage.groupBy { it }
        .mapValues { it.value.count().toDouble()/count }
        .mapKeys { println(it.key); it.key.toDouble()/max }
        .toSortedMap(object : Comparator<Double> {
            override fun compare(p0: Double, p1: Double): Int {
                return (p1-p0).compareTo(0)
            }
        })
Run Code Online (Sandbox Code Playgroud)

它运作得很好.但是IDE一直建议我将Comparator对象转换为lambda,我就这样做了:

val dataMap = sensoryDataUsage.groupBy { it }
        .mapValues { it.value.count().toDouble()/count }
        .mapKeys { println(it.key); it.key.toDouble()/max }
        .toSortedMap {x, y -> (y-x).compareTo(0)}
Run Code Online (Sandbox Code Playgroud)

这个工作很糟糕.但是,它无法编译:

Error:(32, 14) Kotlin: Type inference failed: fun <K, V> Map<out K, V>.toSortedMap(comparator: Comparator<in K>): SortedMap<K, V> cannot be applied to receiver: Map<Double, Double>  arguments: ((Double, Double) -> Int)
Run Code Online (Sandbox Code Playgroud)

出了什么问题?提前致谢.

A. *_*huk 8

试试这种方式:

val dataMap = sensoryDataUsage.groupBy { it }
        .mapValues { it.value.count().toDouble()/count }
        .mapKeys { println(it.key); it.key.toDouble()/max }
        .toSortedMap(Comparator<Double> { p0, p1 -> (p1-p0).compareTo(0) })
Run Code Online (Sandbox Code Playgroud)

工作代码有很多答案,但我会尝试解释为什么代码不能正常工作.看看这个lambda:

p0, p1 -> (p1-p0).compareTo(0)
Run Code Online (Sandbox Code Playgroud)

它将生成一个方法,在我们的例子中,返回最后一个被调用方法内部指定的类型 - compareTo.换句话说 - 这个lambda将返回整数.但是你的代码需要一个double,所以你应该指定返回值的类型Double.现在,当您有理由可以随意使用任何建议的解决方案,这更适合您.

  • 谢谢你的回答,但我不明白.你说"这个lambda会返回整数.但是你的代码需要一个double"但是Comparator的compareTo方法需要返回一个int,而不是一个Double.更重要的是,如果我用"p0,p1 - > 0.0"替换lambda,尽管返回Double,它仍然不起作用.据我所知,这是因为编译器无法推断出p0和p1的类型,但我不知道为什么(有趣的是,它可以推断出Collections.sort(...)的类型). (2认同)