Idioms

    provides a Customer class with the following functionality:

    • getters (and setters in case of vars) for all properties
    • equals()
    • hashCode()
    • toString()
    • copy()
    • component1(), component2(), …, for all properties (see Data classes)

    Default values for function parameters

    1. fun foo(a: Int = 0, b: String = "") { ... }

    Filtering a list

    1. val positives = list.filter { x -> x > 0 }

    Or alternatively, even shorter:

    1. val positives = list.filter { it > 0 }

    Checking element presence in a collection.

    1. if ("john@example.com" in emailsList) { ... }
    2. if ("jane@example.com" !in emailsList) { ... }

    String Interpolation

    1. println("Name $name")

    Instance Checks

    1. when (x) {
    2. is Foo -> ...
    3. is Bar -> ...
    4. else -> ...
    5. }

    Traversing a map/list of pairs

    1. for ((k, v) in map) {
    2. println("$k -> $v")
    3. }

    Using ranges

    1. for (i in 1..100) { ... } // closed range: includes 100
    2. for (i in 1 until 100) { ... } // half-open range: does not include 100
    3. for (x in 2..10 step 2) { ... }
    4. if (x in 1..10) { ... }

    Read-only list

    1. val list = listOf("a", "b", "c")

    Read-only map

    1. val map = mapOf("a" to 1, "b" to 2, "c" to 3)

    Accessing a map

    1. println(map["key"])
    2. map["key"] = value

    Extension Functions

    1. fun String.spaceToCamelCase() { ... }
    2. "Convert this to camelcase".spaceToCamelCase()

    Creating a singleton

    1. object Resource {
    2. val name = "Name"
    3. }

    Instantiate an abstract class

    1. abstract class MyAbstractClass {
    2. abstract fun doSomething()
    3. abstract fun sleep()
    4. }
    5. fun main() {
    6. val myObject = object : MyAbstractClass() {
    7. override fun doSomething() {
    8. // ...
    9. override fun sleep() { // ...
    10. }
    11. }
    12. myObject.doSomething()
    13. }

    If not null shorthand

    1. val files = File("Test").listFiles()
    2. println(files?.size)

    If not null and else shorthand

    1. val files = File("Test").listFiles()
    2. println(files?.size ?: "empty")

    Executing a statement if null

    1. val values = ...
    2. val email = values["email"] ?: throw IllegalStateException("Email is missing!")

    Get first item of a possibly empty collection

    1. val emails = ... // might be empty
    2. val mainEmail = emails.firstOrNull() ?: ""

    Execute if not null

    1. val value = ...
    2. value?.let {
    3. ... // execute this block if not null
    4. }

    Map nullable value if not null

    1. val value = ...
    2. val mapped = value?.let { transformValue(it) } ?: defaultValue
    3. // defaultValue is returned if the value or the transform result is null.

    Return on when statement

    1. fun transform(color: String): Int {
    2. return when (color) {
    3. "Red" -> 0
    4. "Green" -> 1
    5. "Blue" -> 2
    6. else -> throw IllegalArgumentException("Invalid color param value")
    7. }
    8. }
    1. fun test() {
    2. val result = try {
    3. count()
    4. throw IllegalStateException(e)
    5. }
    6. // Working with result
    7. }

    ‘if’ expression

    Builder-style usage of methods that return Unit

    1. fun arrayOfMinusOnes(size: Int): IntArray {
    2. return IntArray(size).apply { fill(-1) }
    3. }

    Single-expression functions

    1. fun theAnswer() = 42

    This is equivalent to

    1. fun theAnswer(): Int {
    2. return 42
    3. }

    This can be effectively combined with other idioms, leading to shorter code. E.g. with the when-expression:

    1. "Red" -> 0
    2. "Green" -> 1
    3. "Blue" -> 2
    4. else -> throw IllegalArgumentException("Invalid color param value")
    5. }

    Calling multiple methods on an object instance (with)

    1. class Turtle {
    2. fun penDown()
    3. fun penUp()
    4. fun turn(degrees: Double)
    5. fun forward(pixels: Double)
    6. }
    7. val myTurtle = Turtle()
    8. with(myTurtle) { //draw a 100 pix square
    9. penDown()
    10. for (i in 1..4) {
    11. forward(100.0)
    12. turn(90.0)
    13. }
    14. penUp()
    15. }

    Configuring properties of an object (apply)

    1. val myRectangle = Rectangle().apply {
    2. length = 4
    3. breadth = 5
    4. color = 0xFAFAFA
    5. }

    Java 7’s try with resources

    1. val stream = Files.newInputStream(Paths.get("/some/file.txt"))
    2. stream.buffered().reader().use { reader ->
    3. println(reader.readText())
    4. }

    Convenient form for a generic function that requires the generic type information

    1. // public final class Gson {
    2. // ...
    3. // public <T> T fromJson(JsonElement json, Class<T> classOfT) throws JsonSyntaxException {
    4. // ...
    5. inline fun <reified T: Any> Gson.fromJson(json: JsonElement): T = this.fromJson(json, T::class.java)

    Consuming a nullable Boolean

    1. val b: Boolean? = ...
    2. if (b == true) {
    3. ...
    4. } else {
    5. // `b` is false or null
    6. }

    Swapping two variables

    1. var a = 1
    2. var b = 2

    TODO(): Marking code as incomplete

    Kotlin’s standard library has a TODO() function that will always throw a NotImplementedError. Its return type is Nothing so it can be used regardless of expected type. There’s also an overload that accepts a reason parameter:

    IntelliJ IDEA’s kotlin plugin understands the semantics of TODO() and automatically adds a code pointer in the TODO tool window.