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