Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 3

Conditional Logic with If/Else and When

Recommended resources

Hello! Welcome back.

In our last lesson, we covered how to declare variables with val and var, and how Kotlin’s powerful type inference makes your code more concise while maintaining type safety. You also learned about basic types and how to use string templates for cleaner string formatting.

Today, we'll dive into one of the most significant areas where Kotlin improves upon Java: conditional logic. We’ll explore how if/else and when are not just statements that perform an action, but powerful expressions that can return a value. This is a fundamental concept that leads to more expressive and readable code.

By the end of this lesson, you will be able to write sophisticated conditional logic using Kotlin's if/else and when expressions, moving beyond the constructs you're familiar with in Java.

if/else: More Than Just a Statement

In Java, if/else is a statement used to control which block of code executes. If you want to assign a value based on a condition, you typically use a ternary operator or declare a variable and assign it within the if and else blocks.

Kotlin simplifies this. An if/else block can be an expression, meaning it evaluates to a value that you can directly assign to a variable.

Kotlin If/Else Expression Syntax
This image illustrates the concise syntax for using an if/else block as an expression in Kotlin. The result of the conditional is assigned directly to the `name` variable.

Let's watch a video that demonstrates this concept. It starts with the familiar if/else structure and then shows how to use it as an expression, a key feature for writing idiomatic Kotlin.

Kotlin Crash Course for Java Developers

This segment from 'Kotlin Crash Course for Java Developers' on the Coding Master channel clearly demonstrates the transition from a standard if/else statement to an if/else expression.

Watch from 00:13:53 to 00:18:19. Pay close attention to how the print statements inside the if/else block are removed and the conditional's result is assigned to a results variable.

As you saw, the code becomes much cleaner:

Java-style (and valid in Kotlin):

val age = 25
val message: String
if (age >= 21) {
    message = "You are allowed to drink."
} else {
    message = "You are not allowed to drink."
}
println(message)

Idiomatic Kotlin using an expression:

val age = 25
val message = if (age >= 21) {
    "You are allowed to drink." // This value is returned
} else {
    "You are not allowed to drink." // This value is returned
}
println(message)

Notice that when if is used as an expression, the else branch is mandatory. The value of the last expression in a block becomes the value of that block. This is analogous to Java's ternary operator (condition ? value_if_true : value_if_false), but often more readable, especially for multi-line logic.


when: Kotlin's Powerful switch

If you're looking for Java's switch statement in Kotlin, you'll find its more powerful and flexible successor: the when expression. It can handle a wide variety of use cases, making it one of Kotlin's most versatile features.

For a developer with your background, the best way to understand when is to see how it compares directly to Java's switch.

Kotlin Switch Explained: Unlocking the Power of Kotlin when

This article, 'Kotlin Switch Explained', is written specifically for developers familiar with constructs like Java's switch. It provides a great starting point for understanding when.

Read the following sections: The introduction, which contrasts when with Java's switch. 'Difference between expression and statement in when'. 'Difference between when in Kotlin vs. switch in Java' for a side-by-side syntax comparison. 'Compare when to if... else in Kotlin' to see how when improves readability.

Key takeaways from this comparison are:

  • No break needed: Kotlin's when automatically stops at the first matching branch.
  • else for default: The default case from switch is replaced by the else branch in when.
  • Expression or Statement: Just like if, when can be used as an expression to return a value.

Now, let's see when in action. The following video segment continues from where we left off and provides a practical demonstration.

Kotlin Crash Course for Java Developers

This part of the 'Kotlin Crash Course' shows how to use when to handle multiple conditions, assign the result to a variable, and combine different cases into a single branch.

Watch from 00:18:19 to 00:26:06. Observe how when is used both as a statement (with println in each branch) and as an expression (returning a food value).


Advanced Capabilities of when

The when expression goes far beyond simple value matching. It can replace complex if-else if chains and handle a variety of checks, making your code both concise and easy to read.

Let's explore some of these advanced features in the official Kotlin documentation.

Conditions and loops | Kotlin Documentation

The official Kotlin documentation provides a comprehensive look at the advanced features of when expressions.

Read the sections 'When expressions and statements' and 'Other ways to use when'. Focus on the code examples that demonstrate: Combining multiple conditions in one branch with a comma. Using the in keyword to check for values in a range (e.g., in 1..10). Using the is keyword for type checking. Using when without an argument to check arbitrary boolean expressions.

Here are some examples of what makes when so powerful:

1. Combining multiple cases:

val day = "Sunday"
when (day) {
    "Saturday", "Sunday" -> println("It's the weekend!")
    else -> println("It's a weekday.")
}

2. Using ranges and collections:
In your e-commerce app, you could use this to categorize products by price.

val price = 49.99
when (price) {
    in 0.0..9.99 -> println("Inexpensive")
    in 10.0..99.99 -> println("Mid-range")
    else -> println("Premium")
}

3. Checking types with is (Smart Casting):

fun checkType(obj: Any) {
    when (obj) {
        is String -> println("It's a String with length ${obj.length}") // obj is automatically cast to String
        is Int -> println("It's an Int with value $obj")
        else -> println("Unknown type")
    }
}
checkType("Hello Kotlin")
checkType(101)

Notice that after checking is String, you can directly access String properties like length without an explicit cast. This is called smart casting.

4. Using when without an argument:
This allows you to replace a complex if-else if chain.

val itemCount = 15
val hasPremiumMembership = false

val shippingCost = when {
    itemCount == 0 -> 0.0
    hasPremiumMembership -> 0.0
    itemCount > 10 -> 5.0
    else -> 10.0
}
println("Shipping cost: $$shippingCost")

Practice

Let's apply these concepts. Imagine you're working on the back-end for your recipe book app. You need to write a function getRecipeDifficulty that takes the number of ingredients (ingredientCount) and the preparation time in minutes (prepTime) and returns a String indicating the difficulty: "Easy", "Medium", or "Hard".

The rules are:

  • A recipe is "Hard" if it has more than 10 ingredients and takes more than 60 minutes.
  • A recipe is "Easy" if it has 5 or fewer ingredients and takes 30 minutes or less.
  • Otherwise, the recipe is "Medium".

Implement this function using a when expression without an argument.

Click for the solution
fun getRecipeDifficulty(ingredientCount: Int, prepTime: Int): String {
    return when {
        ingredientCount > 10 && prepTime > 60 -> "Hard"
        ingredientCount <= 5 && prepTime <= 30 -> "Easy"
        else -> "Medium"
    }
}

fun main() {
    println("Recipe 1 (12 ingredients, 75 min): ${getRecipeDifficulty(12, 75)}") // Expected: Hard
    println("Recipe 2 (4 ingredients, 20 min): ${getRecipeDifficulty(4, 20)}")   // Expected: Easy
    println("Recipe 3 (8 ingredients, 45 min): ${getRecipeDifficulty(8, 45)}")    // Expected: Medium
    println("Recipe 4 (15 ingredients, 45 min): ${getRecipeDifficulty(15, 45)}")  // Expected: Medium
}

This solution uses a when expression without a subject, where each branch is a boolean condition. The function returns the String value from the first branch that evaluates to true. This is a perfect example of how when can create clean and readable business logic.


Key Takeaways

  • Conditionals as Expressions: Both if and when can be used as expressions in Kotlin, returning a value that can be assigned directly to a variable. This leads to more concise and functional-style code.
  • when is a Supercharged switch: It replaces Java's switch with more power and flexibility. You don't need break statements.
  • Versatility of when: You can use when to check against multiple values, ranges (in), types (is), and arbitrary boolean expressions, making it a highly versatile tool for controlling program flow.

Next Steps

You've now mastered conditional logic in Kotlin. The next logical step is to handle repetitive tasks. In our next lesson, we will cover iteration, exploring Kotlin's for, while, and do-while loops and how they work with ranges and collections.