Jue Wang
Jue Wang

Reputation: 85

convert comparator to lambda in Kotlin

There is a code snipt in my Kotlin code:

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)
            }
        })

It worked just fine. However the IDE keeps suggesting me to convert that Comparator object to a lambda, and I did just that:

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)}

This shold work. However, it can't be compiled:

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)

Any ideas what went wrong? Thanks in advance.

Upvotes: 7

Views: 5054

Answers (4)

John Moore
John Moore

Reputation: 8274

Try

{x, y -> y.compareTo(x)}

Upvotes: 0

A. Shevchuk
A. Shevchuk

Reputation: 2169

Try this way:

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) })

You have a lot of answers with working code, but I'll try to explain why didn't your code work. Take a look on this lambda:

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

It would generate a method which one returns type specified inside of the last called method, in our case - compareTo. In another words - this lambda would return integer. But your code needs a double, so you should specify type of returning value as Double. Now when you got a reasons feel free to use any of suggested solutions, which fits you better.

Upvotes: 9

holi-java
holi-java

Reputation: 30676

your code should be like this:

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)});

OR you can remove the y-x expression:

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)});

OR using compareByDescending instead:

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

Upvotes: 3

Akshar Patel
Akshar Patel

Reputation: 9378

Replace

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

with

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

Upvotes: 0

Related Questions