pondělí 17. prosince 2018

Equivalent closures in Groovy and Kotlin

Equivalent closures in Groovy and Kotlin.md

Equivalent closures in Groovy and Kotlin

Closures in Groovy and Kotlin are very similar, but have different names. Here is is list with few of them.

Project with samples is here:
https://github.com/bugs84/samples/tree/master/kotlin-groovy-closures

Groovy Kotlin
each forEach
collect map
findAll filter
find find
groupBy groupBy
eachWithIndex forEachIndexed
with run, let
with :-/ apply, also

Note: Not every think is absolutely same, but it’s at least quite similar.

each vs. forEach

def sum = 0
[1, 2, 3].each { sum += it }
assert sum == 6
var sum = 0  
listOf(1, 2, 3).forEach { sum += it }  
assertThat(sum).isEqualTo(6)

collect vs. map

List<String> result = [1, 2, 3].collect { "S-" + it }  
assert result == ["S-1", "S-2", "S-3"]
val result = listOf(1, 2, 3).map { "S-" + it }  
assertThat(result).isEqualTo(listOf("S-1", "S-2", "S-3"))

findAll vs. filter

assert [1, 2, 3, 4, 5].findAll { it < 3 } == [1, 2]
assertThat(
        listOf(1, 2, 3, 4, 5).filter { it < 3 }
).isEqualTo(
        listOf(1, 2)
)

find vs. find

assert [1, 2, 3, 4, 5].find { it < 3 } == 1
assertThat(  
        listOf(1, 2, 3, 4, 5).find { it < 3 }  
).isEqualTo(
        1
)

groupBy vs. groupBy

Map<Integer, List<Integer>> groupBy = [1, 2, 3, 4, 5, 6, 7].groupBy { it % 3 }  
assert groupBy == [  
        0: [3, 6],  
        1: [1, 4, 7],  
        2: [2, 5]  
]
val groupBy: Map<Int, List<Int>> = listOf(1, 2, 3, 4, 5, 6, 7).groupBy { it % 3 }  
assertThat(groupBy).isEqualTo(
    mapOf(  
        0 to listOf(3, 6),  
        1 to listOf(1, 4, 7),  
        2 to listOf(2, 5)  
    ))

eachWithIndex vs. forEachIndexed

def result = ""  
["A", "B"].eachWithIndex { entry, index ->  
    result += "$index:$entry, "  
}  
assert result == "0:A, 1:B, "
var result = ""  
listOf("A", "B").forEachIndexed { index, entry ->  
  result += "$index:$entry, "  
}  
assertThat(result).isEqualTo("0:A, 1:B, ")

Note: entry and index are in different order

with vs. run

assert "string".with {  
    length()  
} == 6
assertThat(  
    "string".run {  
        length  
    }  
).isEqualTo(6)

with/run can be used just for for creating an scope:

assert with {  
    "AAA"  
} == "AAA"
assertThat(  
        run {  
            "AAA"  
        }  
).isEqualTo("AAA")

In Groovy with works as Kotlin let as well. See next example:

with vs. let

assert "string".with {  
    it.length()  
} == 6
assertThat(  
        "string".let {  
            it.length  
        }  
).isEqualTo(6)

with vs. apply

assert "string".with {  
    println length()  
    it //  :-/  
} == "string"
assertThat(  
        "string".apply {  
            println(length)  
        }
).isEqualTo("string")

with vs. also

assert "string".with {  
    println it.length()  
    it //  :-/  
} == "string"
assertThat(  
        "string".also {  
            println(it.length)  
        }  
).isEqualTo("string")