2017-06-23 21 views
5

Có một snipt mã trong mã Kotlin tôi:convert so sánh để lambda trong 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) 
      } 
     }) 

Nó chỉ làm việc tốt. Tuy nhiên, IDE tiếp tục đề nghị tôi chuyển đổi đối tượng Comparator đó thành một lambda và tôi đã làm điều đó:

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

Công việc này được làm sáng tỏ. Tuy nhiên, nó không thể được biên dịch:

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) 

Bất kỳ ý tưởng gì đã xảy ra? Cảm ơn trước.

+0

Bạn đã chuyển đổi nó bằng tay hoặc áp dụng một ý định cung cấp bởi IDE? – Ilya

Trả lời

6

Hãy thử cách này:

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

Bạn có rất nhiều câu trả lời với mã làm việc, nhưng tôi sẽ cố gắng giải thích lý do tại sao không làm việc mã của bạn. Hãy xem trên lambda này:

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

Nó sẽ tạo ra một phương pháp mà người ta trả về kiểu được chỉ định bên trong của phương pháp được gọi là cuối cùng, trong trường hợp của chúng tôi - compareTo. Nói cách khác - lambda này sẽ trả về số nguyên. Nhưng mã của bạn cần gấp đôi, vì vậy bạn nên chỉ định loại giá trị trả lại là Double. Giờ đây, khi bạn có lý do, hãy sử dụng bất kỳ giải pháp được đề xuất nào phù hợp với bạn hơn.

+1

Cảm ơn bạn đã trả lời, nhưng tôi không hiểu. Bạn nói "lambda này sẽ trả về số nguyên. Nhưng mã của bạn cần gấp đôi" tuy nhiên phương thức compareTo của Comparator cần trả về một int, chứ không phải là Double. Thêm vào vấn đề, nếu tôi thay thế lambda bằng "p0, p1 -> 0.0" thì nó vẫn không hoạt động mặc dù trả về Double. Theo như tôi có thể nói đó là bởi vì trình biên dịch không thể suy ra các loại p0 và p1, nhưng tôi không biết tại sao (thú vị, nó có thể suy ra các kiểu trong trường hợp của Collections.sort (...)). – TheIT

+1

@ TheIT, thực ra bạn đã đúng, nó không thể kế thừa kiểu và tôi cũng không thể nói tại sao nó có thể được thừa kế từ 'Collections.sort' và không thể được thực hiện ở đây. Hmm, xin lỗi, tôi nghĩ compareTo trả về một giá trị với một kiểu đầu vào. Hãy cho tôi biết về điều tra của bạn, có lẽ chúng tôi có thể cải thiện và hoàn thành câu trả lời này –

3

mã của bạn nên là như thế này:

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

HOẶC bạn có thể loại bỏ các biểu hiện 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)}); 

HOẶC sử dụng compareByDescending thay vì:

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

hoặc bạn có thể sử dụng So sánh để chỉ định loại trả lại của lambda –

0

Thay

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

với

.toSortedMap {x:Double, y:Double -> (y-x).compareTo(0)} 
Các vấn đề liên quan