https://kotlinlang.org/docs/reference/idioms.html#string-interpolation
Code Block println("Name $name")
Prefer read-only `val` over mutable `var`
Code Block /* bad */ var counter = 0 for(i in 0..20){ counter += i } /* preferred */ val sum = (0..20).sum()
Unit as a return type
Code Block fun doSomething(): Unit{ println("do something") }
https://kotlinlang.org/docs/reference/idioms.html#single-expression-functions
Code Block fun theAnswer() = 42
https://kotlinlang.org/docs/reference/idioms.html#default-values-for-function-parameters
Code Block fun foo(a: Int = 0, b: String = "") { ... }
...
...
...
Code Block
...
fun theAnswer() = 42
Unit as a return type
...
object Resource { val name = "Name" }
...
...
Code Block
...
when
...
(x) {
...
Extension properties
...
is Foo -> ... is Bar -> ... else -> ... }
https://kotlinlang.org/docs/reference/idioms.html#creating-dtos-pojospocos
Code Block data class Customer(val name: String, val email: String)
Use the fact that `return` and `throw` have type `Nothing`, https://kotlinlang.org/docs/reference/idioms.
...
...
...
...
...
Code Block
...
val x =
...
foo() ?: return notFound() val y = if(conditionSatisfied()){ 1.0 } else { error("Condition is not satisfied"}//throws inside, the type is Nothing }
...
Code Block fun transform(color: String): Int { return when (
...
color) { "Red" -> 0
...
...
"Green" ->
...
1
...
...
"Blue" ->
...
2
...
else -> throw IllegalArgumentException("Invalid color param value") } }
Nullable truth.
Code Block a?.b == true //instead of a?.
...
b ?: false
var x: String?; x = x ?: "Hello"; (analog for dart ?=)
Code Block var x: String? = null x = x ?: "Hello"
Safe chain and elvis (https://kotlinlang.org/docs/reference/idioms.
...
...
...
...
...
Code Block
...
for ((k, v) in map) {
println("$k -> $v")
}
val (a,b) = Pair(1, 2)
val files = File("Test").listFiles() println(files?.size ?: "empty")
...
Code Block
...
val
...
value
...
=
...
...
...
value?.let { ...
...
// execute
...
this
...
block
...
if
...
not
...
null }
https://kotlinlang.org/docs/reference/idioms.html#extension-functions
Code Block fun String.spaceToCamelCase() { ... }
...
"Convert this to camelcase".spaceToCamelCase()
Extension properties
Code Block import java.util.Calendar var Calendar.year get() = get(Calendar.YEAR) set(value) = set(Calendar.YEAR, value) val calendar = Calendar.getInstance() println(calendar.year) // 2020 calendar.year = 2021 println(calendar.year) // 2021
- Using with/let/run to create a scope
- Using apply/also to add a finalizing action
https://kotlinlang.org/docs/reference/idioms.html#configuring-properties-of-an-object-apply https://kotlinlang.org/docs/reference/idioms.html#read-only-list
Code Block val list = listOf("a", "b", "c")
Simple empty collection
Code Block fun doSomething(additionalArguments: List<String> = emptyList())
https://kotlinlang.org/docs/reference/idioms.html#accessing-a-map
Code Block println(map["key"]) map["key"] = value
Destructuring declaration (https://kotlinlang.org/docs/reference/idioms.
...
html#traversing-a-maplist-of-pairs)
Code Block
...
for ((k, v) in map) {
...
https://kotlinlang.org/docs/reference/idioms.html#creating-a-singleton
Code Block |
---|
object Resource {
val name = "Name"
} |
...
println("$k -> $v") } val (a,b) = Pair(1, 2)
Public var with a private/protected setter
Code Block var a: Int = 2 protected set // accessible only in descendents
Mutable private - read-only public collections.
Code Block ptivate val _list = ArrayList<Int>() val list: List<Int> get() = _list
...
...
...
...
...
...
Code Block
...
if ("
...
john@example.com" in emailsList) { ... } if ("jane@example.com" !in emailsList) { ... }
ranges instead of for loops (https://kotlinlang.org/docs/reference/idioms.
...
Code Block
...
for (i in 1..100) { ... } // closed range: includes 100
...
for (i in 1 until 100) { ... } // half-open range: does not include 100 for (x in 2..10 step 2) { ... } for (x in 10 downTo 1) { ...
...
} if (x in 1..10) { ... }
Trailing lambdas (place lambda the last in the function parameters list, try to provide default values for parameters). Try to make such functions inline (to remove lambda creating overhead).
Code Block fun
...
integrate(
...
from:
...
Double
...
= 0.0, to: Double = 1.0, function: (Double)→Double): Double {...} integrate{x→x*x + 2*x + 1} integrate(0.0, Pi){ sin(it) }
.filter.map.reduce (collection processing, higher order functions) (https://kotlinlang.org/docs/reference/idioms.html#filtering-a-list)
Code Block val list: List<Int> = listOf(1,2,3,4,5,6) val result = list .filter{it%2 == 0} //select even numbers .map{it*it} // get square of each element .sumByDouble{it.toDouble()} //use one of reduce operations
Assignment to `if`/`when`/`try`
Code Block val a = if(b>0) 0 else 1
https://kotlinlang.org/docs/reference/idioms.html#trycatch-expression
Code Block fun test() { val result = try { count() } catch (e: ArithmeticException) { throw IllegalStateException(e) } // Working with result }
Code Block val ioResult: IOResult? = try{ readFromFile() //assign result if it read is successful } catch(t: FileNotFoundException){ null // return null if file not found }
https://kotlinlang.org/docs/reference/idioms.html#builder-style-usage-of-methods-that-return-unit
Code Block fun arrayOfMinusOnes(size: Int): IntArray { return IntArray(size).apply { fill(-1) } }
...
https://kotlinlang.org/docs/reference/idioms.html#configuring-properties-of-an-object-apply
...
...
val myRectangle = Rectangle().apply {
length = 4
breadth = 5
color = 0xFAFAFA
}
Scoped use of objects (https://kotlinlang.org/docs/reference/idioms.html#java-7s-try-with-resources)
Code Block val stream = Files.newInputStream(Paths.get("/some/file.txt")) stream.buffered().reader().use { reader -> println(reader.readText()) }
- Companion object. Use companion object as an ID
Factory method instead of constructors
Code Block class Doubles(val list: DoubleArray) @Suppress("FunctionName") fun Doubles(vararg numbers: Number) = Doubles(numbers.map{it.toDouble()}.toDoubleArray()) Doubles(1,2,3)
Lazy properties https://kotlinlang.org/docs/reference/idioms.html#lazy-property
Code Block val p: String by lazy { // compute the string }
Code Block // public final class Gson { // ... // public <T> T fromJson(JsonElement json, Class<T> classOfT) throws JsonSyntaxException { // ... inline fun <reified T: Any> Gson.fromJson(json: JsonElement): T = this.fromJson(json, T::class.java)
Non-local return
Code Block fun foo() { listOf(1, 2, 3, 4, 5).forEach { if (it == 3) return // non-local return directly to the caller of foo() print(it) } println("this point is unreachable"
...
)
...
...
}
...
Factory method instead of constructors
...
Use the fact that `return` and `throw` have type `Nothing`, https://kotlinlang.org/docs/reference/idioms.html#todo-marking-code-as-incomplete
Code Block |
---|
val x = foo() ?: return notFound()
val y = if(conditionSatisfied()){
1.0
} else {
error("Condition is not satisfied"}//throws inside, the type is Nothing
} |
Nullable truth.
Code Block |
---|
a?.b == true
//instead of
a?.b ?: false |
Assignment to `if`/`when`/`try`
Code Block |
---|
val a = if(b>0) 0 else 1 |
Code Block |
---|
val ioResult: IOResult? = try{
readFromFile() //assign result if it read is successful
} catch(t: FileNotFoundException){
null // return null if file not found
} |
...
class Doubles(val list: DoubleArray)
@Suppress("FunctionName")
fun Doubles(vararg numbers: Number) = Doubles(numbers.map{it.toDouble()}.toDoubleArray())
Doubles(1,2,3)
var x: String?; x = x ?: "Hello"; (analog for dart ?=)
Code Block |
---|
var x: String? = null
x = x ?: "Hello" |
Public var with a private/protected setter
Code Block |
---|
var a: Int = 2
protected set // accessible only in descendents |
Mutable private - read-only public collections.
Code Block |
---|
ptivate val _list = ArrayList<Int>()
val list: List<Int> get() = _list |
Trailing lambdas (place lambda the last in the function parameters list, try to provide default values for parameters). Try to make such functions inline (to remove lambda creating overhead).
Code Block |
---|
fun integrate(from: Double = 0.0, to: Double = 1.0, function: (Double)→Double): Double {...}
integrate{x→x*x + 2*x + 1}
integrate(0.0, Pi){ sin(it) }
|
...
- DoubleArray vs Array<Double> vs List<Double>
Unsorted
- Read line
Code Block |
---|
val map: MutableMap<String, Int>
val (a, b) = readlLine()?.split(" ") ?: error("No line to read") // read line and split it by given delimeter and use destructuring declaration
map[a] = b.toInt() // Convert the value on-flight and assign it |
Simple empty collection
- Use JMH for benchmarking