2017-06-23 2 views
5

Es gibt einen Code Schnipsel in meinem Kotlin Code:convert Vergleich Lambda in 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) 
      } 
     }) 

Es funktionierte gut. Allerdings halten die IDE was darauf hindeutet, dass ich Vergleicher Objekt zu einem Lambda zu konvertieren, und ich habe genau das:

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

Diese SHOLD Arbeit. Es kann jedoch nicht kompiliert werden:

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) 

Irgendwelche Ideen, was schief gelaufen ist? Danke im Voraus.

+0

Haben Sie es manuell konvertieren oder die Absicht von der IDE zur Verfügung gestellt gelten? – Ilya

Antwort

6

Versuchen Sie, diese Art und Weise:

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

Sie eine Menge Antworten haben mit funktionierenden Code, aber ich werde versuchen, warum nicht Arbeit Code tat zu erklären. Werfen Sie einen Blick auf dieses Lambda:

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

Es wäre ein Verfahren zu erzeugen, die eine Art innerhalb der letzten aufgerufenen Methode angegeben zurückgibt, in unserem Fall - compareTo. Mit anderen Worten - dieses Lambda würde eine Ganzzahl ergeben. Aber Ihr Code benötigt ein Double, daher sollten Sie den Typ des zurückgegebenen Werts als Double angeben. Wenn Sie einen Grund haben, zögern Sie nicht, eine der vorgeschlagenen Lösungen zu verwenden, die Ihnen besser passen.

+1

Danke für die Antwort, aber ich verstehe nicht. Sie sagten "dieses Lambda würde Ganzzahl zurückgeben. Aber Ihr Code benötigt ein Double", aber die CompareTo-Methode des Comparators muss ein int zurückgeben, nicht ein Double. Genauer gesagt, wenn ich das Lambda durch "p0, p1 -> 0.0" ersetze, funktioniert es trotz der Rückgabe eines Double immer noch nicht. Soweit ich das beurteilen kann, liegt es daran, dass der Compiler die Typen von p0 und p1 nicht ableiten kann, aber ich weiß nicht warum (interessanterweise kann er im Fall von Collections.sort (...) die Typen ableiten). – TheIT

+1

@TheiT, eigentlich hast du Recht, es kann keinen Typ erben und ich kann auch nicht sagen, warum es von 'Collections.sort' vererbt werden könnte und hier nicht gemacht werden könnte. Hmm, sorry, ich dachte compareTo gibt einen Wert mit einer Art von Eingabe zurück. Lassen Sie mich über Ihre Untersuchung wissen, vielleicht können wir diese Antwort verbessern und vervollständigen –

3

Ihr Code sollte wie folgt sein:

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

ODER Sie den y-x Ausdruck entfernen:

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 mit compareByDescending statt:

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

oder Sie können den Comparator verwenden, um den Typ der Lambda-Rückgabe anzugeben –

0

ersetzen

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

mit

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