From Java to Kotlin - Control Flow

If as an expression

If branches can be blocks, that when used as an expression, its last value is the returned value of the block.

// java's ternary statement
final String max = a > b ? a : b

// kotlin's if expression
val max = if(a > b) a else b

As an expression, i0f is required to have an else branch.

When statement and expression

This is similar to Java’s switch.

There’re two forms of when

  1. when that accepts an argument
  2. when without an argument. It matches its argument against all branches until a condition is satisfied

You don’t need to write break statements in each branch.

When with an argument

It matches against different constants. You may combine values with a comma ,

// when with an argument
val greeting = when(x) {
  "English" -> "How are you?"
  "German" -> "Wie geht es dir?"
  "Castillan", "Latino" -> "¿Como estás?"
  else -> "default value"
}

When as an arbitrary expression

when (x) {
  parseInt(s) -> print("s encodes x")
  else -> print("s does not encode x")
}

When with ‘in’ operator

It can check a value for being in or !in a range or a collection.

when (x) {
  in 1..10 -> print("x is in range")
  in validNumbers -> print("x is valid")
  !in 10..20 -> print("x is outside of range")
  else -> print("none")
}

When with Smart Cast

fun startsWithFoo(any: Any): Boolean {
  return when (any) {
    is String -> any.startsWith("Foo")
    else -> false
  }
}

When without an argument

It’s an alternative to an if statement with multiple else if branches

when {
  str.length == 0 -> print("Empty String")
  str.length > 5 -> print("short String")
  else -> print("long String")
}

Ranges and Progressions

A range is an internal between two values, usually numbers. You signal it using the .. operator.

val oneToTen = 1..10

If you can iterate over all the values in a range, it’s called a progression

Ranges are closed or inclusive. This means the second value is also always a part of the range
You can use the in operator to check whether a value is in a range

Ranges aren’t restricted to numbers. Any class that supports comparing instances (implementing java.lang.Comparable interface) can use ranges.

Utility Functions

The downTo() function allows you to iterate numbers in reverse order

// prints '4321'
for (i in 4 downTo 1) print(i)

The step() function allows you to iterate over numbers with an arbitrary step.
It allows you to skip some numbers

// prints '13'
for (i in 1..4 step 2) print(i)

Combine them

// prints '42'
for (i in 4 downTo 1 step 2) print(i)

The until() function it’s used to create a range which does not include its end element.

// 10 is excluded
for (i in 1 until 10) print(i)

Iterate over an array

Arrays have an extension funcion called index which can be used to iterate over an array.

for (index in array.indices) {
  println("Element $index is ${array[index]}")
}

Return and jump

This is frowned upon to use, because it makes everything harder to maintain.

Break and Continue Labels

Any expression in Kotlin may be marked with a label. A break qualified with a label jumps to the execution point right after the loop marked with that label.

loop@ for (i in 1..100) {
  for (j in 1..100) {
    if (...) break@loop
  }
}

Return at Labels

You can use a return and a label to jump out of a nested function

fun foo() {
  ints.forEach {
    if (it == 0) return@forEach
    print(it)
  }
}

This is frowned upon to use, because it makes everything harder to maintain.