Conditional Statements
Overview
Kotlin provides powerful conditional statements, including if expressions and when expressions. Unlike many other languages, conditional statements in Kotlin are expressions, meaning they can return values, making code more concise and functional.
if Expressions
Basic if Statement
kotlin
fun main() {
val score = 85
// Basic if statement
if (score >= 60) {
println("Passed!")
}
// if-else statement
if (score >= 90) {
println("Excellent")
} else {
println("Good")
}
// if-else if-else chain
if (score >= 90) {
println("Grade: A")
} else if (score >= 80) {
println("Grade: B")
} else if (score >= 70) {
println("Grade: C")
} else if (score >= 60) {
println("Grade: D")
} else {
println("Grade: F")
}
}if as an Expression
kotlin
fun main() {
val score = 85
// if expression returns a value
val grade = if (score >= 90) {
"A"
} else if (score >= 80) {
"B"
} else if (score >= 70) {
"C"
} else if (score >= 60) {
"D"
} else {
"F"
}
println("Grade: $grade")
// Simplified if expression
val status = if (score >= 60) "Pass" else "Fail"
println("Exam status: $status")
// Complex if expression
val message = if (score >= 90) {
val bonus = score - 90
"Excellent! Bonus points: $bonus"
} else {
val needed = 90 - score
"Need $needed more points to reach excellent"
}
println(message)
}Practical Applications of Conditional Expressions
kotlin
fun main() {
// Null check
val name: String? = "Alice"
val displayName = if (name != null) name else "Anonymous"
println("Display name: $displayName")
// Range check
val temperature = 25
val weather = if (temperature < 0) {
"Freezing"
} else if (temperature < 10) {
"Cold"
} else if (temperature < 20) {
"Cool"
} else if (temperature < 30) {
"Warm"
} else {
"Hot"
}
println("Weather: $weather (${temperature}°C)")
// Boolean logic
val age = 20
val hasLicense = true
val canDrive = if (age >= 18 && hasLicense) {
"Can drive"
} else if (age < 18) {
"Too young"
} else {
"Needs license"
}
println("Driving status: $canDrive")
}when Expressions
Basic when Expression
kotlin
fun main() {
val dayOfWeek = 3
// Basic when expression
when (dayOfWeek) {
1 -> println("Monday")
2 -> println("Tuesday")
3 -> println("Wednesday")
4 -> println("Thursday")
5 -> println("Friday")
6 -> println("Saturday")
7 -> println("Sunday")
else -> println("Invalid day")
}
// when as an expression
val dayName = when (dayOfWeek) {
1 -> "Monday"
2 -> "Tuesday"
3 -> "Wednesday"
4 -> "Thursday"
5 -> "Friday"
6 -> "Saturday"
7 -> "Sunday"
else -> "Invalid"
}
println("Day: $dayName")
}Advanced when Usage
kotlin
fun main() {
val number = 15
// Multiple value matching
when (number) {
1, 2, 3 -> println("Small number")
4, 5, 6 -> println("Medium number")
7, 8, 9 -> println("Larger number")
else -> println("Other number")
}
// Range matching
when (number) {
in 1..10 -> println("Between 1 and 10")
in 11..20 -> println("Between 11 and 20")
in 21..30 -> println("Between 21 and 30")
else -> println("Out of range")
}
// Type checking
val obj: Any = "Hello"
when (obj) {
is String -> println("String: $obj, length: ${obj.length}")
is Int -> println("Integer: $obj")
is Boolean -> println("Boolean: $obj")
else -> println("Unknown type")
}
// Condition expressions
val score = 85
when {
score >= 90 -> println("Excellent")
score >= 80 -> println("Good")
score >= 70 -> println("Average")
score >= 60 -> println("Pass")
else -> println("Fail")
}
}Complex when Expression Applications
kotlin
enum class Color { RED, GREEN, BLUE, YELLOW, ORANGE, PURPLE }
fun mixColors(color1: Color, color2: Color): String {
return when (setOf(color1, color2)) {
setOf(Color.RED, Color.YELLOW) -> "Orange"
setOf(Color.YELLOW, Color.BLUE) -> "Green"
setOf(Color.BLUE, Color.RED) -> "Purple"
else -> "Unknown mixed color"
}
}
fun getColorInfo(color: Color): String {
return when (color) {
Color.RED -> {
val wavelength = 700
"Red - Wavelength: ${wavelength}nm"
}
Color.GREEN -> {
val wavelength = 550
"Green - Wavelength: ${wavelength}nm"
}
Color.BLUE -> {
val wavelength = 450
"Blue - Wavelength: ${wavelength}nm"
}
else -> "Other color"
}
}
fun main() {
println("Color mixing:")
println(mixColors(Color.RED, Color.YELLOW))
println(mixColors(Color.BLUE, Color.YELLOW))
println("\nColor info:")
println(getColorInfo(Color.RED))
println(getColorInfo(Color.GREEN))
}Nested Conditional Statements
Complex Conditional Logic
kotlin
data class User(val name: String, val age: Int, val isVip: Boolean, val balance: Double)
fun checkAccess(user: User, requestedAmount: Double): String {
return if (user.age >= 18) {
if (user.isVip) {
if (user.balance >= requestedAmount) {
"VIP user, transaction approved"
} else {
"VIP user, insufficient balance, but can overdraft"
}
} else {
if (user.balance >= requestedAmount) {
"Regular user, transaction approved"
} else {
"Regular user, insufficient balance"
}
}
} else {
"Minor user, requires guardian consent"
}
}
// Refactoring nested if using when
fun checkAccessImproved(user: User, requestedAmount: Double): String {
return when {
user.age < 18 -> "Minor user, requires guardian consent"
user.isVip && user.balance >= requestedAmount -> "VIP user, transaction approved"
user.isVip && user.balance < requestedAmount -> "VIP user, insufficient balance, but can overdraft"
!user.isVip && user.balance >= requestedAmount -> "Regular user, transaction approved"
else -> "Regular user, insufficient balance"
}
}
fun main() {
val users = listOf(
User("Alice", 25, true, 1000.0),
User("Bob", 17, false, 500.0),
User("Charlie", 30, false, 100.0),
User("Diana", 28, true, 50.0)
)
val requestAmount = 200.0
println("Access check results:")
users.forEach { user ->
val result = checkAccessImproved(user, requestAmount)
println("${user.name}: $result")
}
}Best Practices for Conditional Statements
1. Prefer when Over Complex if-else Chains
kotlin
// Not recommended: Complex if-else chain
fun getGradeBad(score: Int): String {
if (score >= 90) {
return "A"
} else if (score >= 80) {
return "B"
} else if (score >= 70) {
return "C"
} else if (score >= 60) {
return "D"
} else {
return "F"
}
}
// Recommended: Use when expression
fun getGradeGood(score: Int): String = when {
score >= 90 -> "A"
score >= 80 -> "B"
score >= 70 -> "C"
score >= 60 -> "D"
else -> "F"
}
fun main() {
val score = 85
println("Grade: ${getGradeGood(score)}")
}2. Leverage Smart Casts
kotlin
fun processValue(value: Any?) {
when (value) {
null -> println("Value is null")
is String -> {
// Smart cast: value is automatically cast to String
println("String value: '$value', length: ${value.length}")
if (value.isNotEmpty()) {
println("First character: ${value[0]}")
}
}
is Int -> {
// Smart cast: value is automatically cast to Int
println("Integer value: $value")
if (value > 0) {
println("Positive")
} else if (value < 0) {
println("Negative")
} else {
println("Zero")
}
}
is List<*> -> {
// Smart cast: value is automatically cast to List
println("List value: $value, size: ${value.size}")
}
else -> println("Unknown type: ${value::class.simpleName}")
}
}
fun main() {
val values = listOf("Hello", 42, null, listOf(1, 2, 3), 3.14)
values.forEach { processValue(it) }
}3. Use Expressions Instead of Statements
kotlin
// Not recommended: Using statements
fun getStatusBad(isOnline: Boolean, hasMessages: Boolean): String {
var status: String
if (isOnline) {
if (hasMessages) {
status = "Online - New messages"
} else {
status = "Online"
}
} else {
status = "Offline"
}
return status
}
// Recommended: Use expressions
fun getStatusGood(isOnline: Boolean, hasMessages: Boolean): String {
return when {
isOnline && hasMessages -> "Online - New messages"
isOnline -> "Online"
else -> "Offline"
}
}
// Even more concise
fun getStatusBest(isOnline: Boolean, hasMessages: Boolean) = when {
isOnline && hasMessages -> "Online - New messages"
isOnline -> "Online"
else -> "Offline"
}
fun main() {
println(getStatusBest(true, true))
println(getStatusBest(true, false))
println(getStatusBest(false, false))
}Practical Examples
User Permission System
kotlin
enum class Role { ADMIN, MODERATOR, USER, GUEST }
enum class Permission { READ, WRITE, DELETE, MANAGE_USERS }
data class UserAccount(val name: String, val role: Role, val isActive: Boolean)
class PermissionChecker {
fun hasPermission(user: UserAccount, permission: Permission): Boolean {
if (!user.isActive) return false
return when (user.role) {
Role.ADMIN -> true // Admin has all permissions
Role.MODERATOR -> when (permission) {
Permission.READ, Permission.WRITE, Permission.DELETE -> true
Permission.MANAGE_USERS -> false
}
Role.USER -> when (permission) {
Permission.READ, Permission.WRITE -> true
Permission.DELETE, Permission.MANAGE_USERS -> false
}
Role.GUEST -> permission == Permission.READ
}
}
fun getAccessLevel(user: UserAccount): String {
return when {
!user.isActive -> "Account disabled"
user.role == Role.ADMIN -> "Full access"
user.role == Role.MODERATOR -> "Moderator access"
user.role == Role.USER -> "Standard user access"
user.role == Role.GUEST -> "Read-only access"
else -> "Unknown access level"
}
}
}
fun main() {
val users = listOf(
UserAccount("Admin", Role.ADMIN, true),
UserAccount("Moderator", Role.MODERATOR, true),
UserAccount("User", Role.USER, true),
UserAccount("Guest", Role.GUEST, true),
UserAccount("Banned", Role.USER, false)
)
val checker = PermissionChecker()
println("Permission check results:")
users.forEach { user ->
println("\n${user.name} (${user.role}):")
println(" Access level: ${checker.getAccessLevel(user)}")
Permission.values().forEach { permission ->
val hasAccess = checker.hasPermission(user, permission)
println(" $permission: ${if (hasAccess) "✓" else "✗"}")
}
}
}Calculator Application
kotlin
enum class Operation { ADD, SUBTRACT, MULTIPLY, DIVIDE, POWER, MODULO }
class Calculator {
fun calculate(a: Double, b: Double, operation: Operation): Result<Double> {
return when (operation) {
Operation.ADD -> Result.success(a + b)
Operation.SUBTRACT -> Result.success(a - b)
Operation.MULTIPLY -> Result.success(a * b)
Operation.DIVIDE -> {
if (b != 0.0) {
Result.success(a / b)
} else {
Result.failure(ArithmeticException("Division by zero"))
}
}
Operation.POWER -> Result.success(kotlin.math.pow(a, b))
Operation.MODULO -> {
if (b != 0.0) {
Result.success(a % b)
} else {
Result.failure(ArithmeticException("Modulo by zero"))
}
}
}
}
fun getOperationSymbol(operation: Operation): String = when (operation) {
Operation.ADD -> "+"
Operation.SUBTRACT -> "-"
Operation.MULTIPLY -> "*"
Operation.DIVIDE -> "/"
Operation.POWER -> "^"
Operation.MODULO -> "%"
}
}
fun main() {
val calculator = Calculator()
val testCases = listOf(
Triple(10.0, 5.0, Operation.ADD),
Triple(10.0, 3.0, Operation.SUBTRACT),
Triple(4.0, 3.0, Operation.MULTIPLY),
Triple(15.0, 3.0, Operation.DIVIDE),
Triple(15.0, 0.0, Operation.DIVIDE), // Error case
Triple(2.0, 3.0, Operation.POWER),
Triple(17.0, 5.0, Operation.MODULO)
)
println("Calculator test:")
testCases.forEach { (a, b, op) ->
val symbol = calculator.getOperationSymbol(op)
val result = calculator.calculate(a, b, op)
when {
result.isSuccess -> {
val value = result.getOrNull()
println("$a $symbol $b = $value")
}
result.isFailure -> {
val error = result.exceptionOrNull()
println("$a $symbol $b = Error: ${error?.message}")
}
}
}
}Performance Considerations
when Expression Optimization
kotlin
// Compiler optimizes when expressions
fun optimizedWhen(value: Int): String {
return when (value) {
1, 2, 3, 4, 5 -> "Small number" // Compiler may generate jump table
in 6..10 -> "Medium number"
in 11..100 -> "Large number"
else -> "Very large number"
}
}
// For enums, compiler generates efficient code
enum class Status { PENDING, PROCESSING, COMPLETED, FAILED }
fun getStatusMessage(status: Status): String = when (status) {
Status.PENDING -> "Waiting to process"
Status.PROCESSING -> "Processing"
Status.COMPLETED -> "Completed"
Status.FAILED -> "Failed"
}Next Steps
After mastering conditional statements, let's learn about loop statements in Kotlin, including for loops and while loops.
Next Chapter: Loops
Exercises
- Create a grading system that assigns grades and comments based on scores
- Implement a simple state machine using when expressions for state transitions
- Write a function to determine if a year is a leap year
- Design a game character class system that assigns different skills based on class
- Create a smart recommendation system that recommends content based on user preferences