0

I converted my Java files to Kotlin. And I fixed most of them. However, I don't understand this part using Comparator.

wordItems.sortWith(Comparator { (_, word), (_, word) ->
    val size1 = word!!.length
    val size2 = word.length
    if (size1 < size2) {
        return@Collections.sort - 1
    } else if (size1 == size2) {
        return@Collections.sort 0
    } else {
        return@Collections.sort 1
    }
})

And this one also, I don't understand.

Collections.sort(wordItems) { (_, word), (_, word) ->
    val size1 = word!!.length
    val size2 = word.length
    if (size1 < size2) {
        return@Collections.sort - 1
    } else if (size1 == size2) {
        return@Collections.sort 0
    } else {
        return@Collections.sort 1
    }
}

How can I change this to make it work?

c-an
  • 3,543
  • 5
  • 35
  • 82
  • 2
    Your question is too broad. Please tell us exactly what it is you don't understand. – avolkmann Jun 26 '19 at 16:08
  • I want them to work using `Comparator`. – c-an Jun 26 '19 at 16:15
  • 2
    They already are using Comparator. Comparator is a functional interface and a lambda defines the compare() method. See also [What does return@ mean?](https://stackoverflow.com/questions/40160489/kotlin-whats-does-return-mean). What I don't understand is that it seems the lambda has two arguments and both of them are identical: `(_, word), (_, word)`. Are you sure both are called `word`? – DodgyCodeException Jun 26 '19 at 16:22

1 Answers1

2

Comparator is a SAM (single abstract method) interface in Java. An implementation of such interface can be instantiated in Kotlin using SAM-conversion technique, so instead of writing an anonymous object implementing Comparator like this:

val comparator = object : Comparator<WordItem> {
    override fun compare(item1: WordItem, item2: WordItem): Int {
        val size1 = item1.word.length
        val size2 = item2.word.length
        ...
    }
}

you can write

val comparator = Comparator<WordItem> { item1, item2 -> 
    val size1 = item1.word.length
    val size2 = item2.word.length
    ...
}

Here I assume that each WordItem has the word property.

It seems that you're comparing items by word length. In that case you can simplify such comparator even more with compareBy function:

wordItems.sortWith(compareBy { it.word.length })

or sortBy function

wordItems.sortBy { it.word.length }
Ilya
  • 21,871
  • 8
  • 73
  • 92
  • I see... So, `return@Collections` doesn't mean anything, right? – c-an Jun 27 '19 at 00:58
  • 1
    Probably `return@Collections.sort` is result of an incorrect Java-to-Kotlin conversion and was intended to return the value 0, 1 or -1 from the lambda function. The correct syntax of this labelled return would be `return@Comparator 0`. Here `Comparator` before lambda function body gives an implicit label with the same name to that lambda. See https://kotlinlang.org/docs/reference/returns.html#return-at-labels for the further reference. – Ilya Jun 27 '19 at 02:39