Table of contents
if Is an Expression
In Java, if is a statement. Since it doesn’t return a value, the ternary operator ? : exists separately. In Kotlin, if itself returns a value, so there’s no ternary operator at all.
val score = 85
val grade = if (score >= 90) "A" else if (score >= 80) "B" else "C"
println(grade) // B
You can also use blocks, where the last line of each block becomes the return value.
val message = if (score >= 60) {
println("Passed!")
"Pass" // This value goes into message
} else {
println("Retake...")
"Fail"
}
Why is this useful? The pattern of declaring a var first and filling in values per condition disappears. With the val + if expression combo, the value is determined at declaration time, eliminating any worry about it changing later.
when
If you’ve used Java’s switch, you’ve likely run into issues like forgetting a break or type limitations. Kotlin’s when has none of these problems.
val day = 3
val dayName = when (day) {
1 -> "Monday"
2 -> "Tuesday"
3 -> "Wednesday"
4 -> "Thursday"
5 -> "Friday"
6, 7 -> "Weekend"
else -> "Unknown"
}
Like if, when is also an expression that can return a value. And it goes beyond simple value comparison — it supports ranges, type checks, and conditional expressions.
val x = 15
when {
x < 0 -> println("Negative")
x in 1..10 -> println("Between 1 and 10")
x is Int -> println("Integer greater than 10")
else -> println("Other")
}
Using when without an argument lets you rewrite an if-else chain in a more readable way. It’s particularly useful for branches with three or more conditions.
Comparing the decision flow of when with and without an argument makes the difference clear.
flowchart LR
Input[Input] --> Check{when form}
Check -->|With argument| A["when(x)<br/>value/range/type matching"]
Check -->|Without argument| B["when { }<br/>arbitrary boolean conditions"]
A --> Branch1[Execute matching case]
B --> Branch2[Execute first true condition]
Branch1 --> Return[Return value / perform action]
Branch2 --> Return
for and Ranges
Kotlin’s for is similar to Java’s enhanced for loop, with the addition of range expressions.
// From 1 to 5 (inclusive)
for (i in 1..5) {
print("$i ") // 1 2 3 4 5
}
.. includes the end value. To exclude the end value, use until.
// Suitable for array index traversal
for (i in 0 until 5) {
print("$i ") // 0 1 2 3 4
}
Reverse order and step adjustments are also supported.
for (i in 5 downTo 1) {
print("$i ") // 5 4 3 2 1
}
for (i in 1..10 step 2) {
print("$i ") // 1 3 5 7 9
}
Here’s a summary of what sequences the range operators produce.
flowchart LR
A["1..5"] --> A1["1, 2, 3, 4, 5<br/>end inclusive"]
B["1 until 5"] --> B1["1, 2, 3, 4<br/>end exclusive"]
C["5 downTo 1"] --> C1["5, 4, 3, 2, 1<br/>reverse"]
D["1..10 step 2"] --> D1["1, 3, 5, 7, 9<br/>custom step"]
When iterating over a list, the approach differs depending on whether you need the index.
val fruits = listOf("Apple", "Banana", "Strawberry")
// When you only need the value
for (fruit in fruits) {
println(fruit)
}
// When you also need the index
for ((index, fruit) in fruits.withIndex()) {
println("$index: $fruit")
}
Much more concise than the Java pattern of for (int i = 0; i < list.size(); i++).
while
while and do-while are almost identical to other languages.
var count = 3
while (count > 0) {
println("Count: $count")
count--
}
do {
println("Executed at least once")
} while (false)
One thing to note: Kotlin doesn’t have a traditional for (int i = 0; i < n; i++) style for loop. It’s entirely replaced by range expressions.
The next part covers Kotlin functions. We’ll see how default parameters, named arguments, and extension functions make code much cleaner.




Loading comments...