在Kotlin中将比较器转换为lambda

时间:2017-06-23 12:58:31

标签: 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)
            }
        })

它运作得很好。但是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)}

这是一个非常重要的工作。但是,它无法编译:

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)

任何想法出了什么问题?提前谢谢。

3 个答案:

答案 0 :(得分: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) })

你有很多工作代码的答案,但我会试着解释为什么你的代码不起作用。看看这个lambda:

p0, p1 -> (p1-p0).compareTo(0)

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

答案 1 :(得分:3)

你的代码应该是这样的:

val dataMap = sensoryDataUsage.groupBy { it }
    .mapValues { it.value.count().toDouble()/count }
    .mapKeys { println(it.key); it.key.toDouble()/max }
    .toSortedMap(Comparator<Double>{x, y -> (y-x).compareTo(0)});

您可以删除y-x表达式:

val dataMap = sensoryDataUsage.groupBy { it }
    .mapValues { it.value.count().toDouble()/count }
    .mapKeys { println(it.key); it.key.toDouble()/max }
    .toSortedMap(Comparator<Double>{x, y -> y.compareTo(x)});

改为使用compareByDescending

val dataMap = sensoryDataUsage.groupBy { it }
    .mapValues { it.value.count().toDouble()/count }
    .mapKeys { println(it.key); it.key.toDouble()/max }
    .toSortedMap(compareByDescending{ it });

答案 2 :(得分:0)

替换

.toSortedMap {x:Double, y:Double -> (y-x).compareTo(0)}

Ctrl+Shift+;