Smart casts in when and if in Kotlin - Time & Space Complexity
We want to understand how the time needed to run code with smart casts in when and if changes as input grows.
How does checking types and branching affect the work done?
Analyze the time complexity of the following code snippet.
fun describe(obj: Any): String {
return when (obj) {
is String -> "String of length ${obj.length}"
is Int -> "Integer value $obj"
else -> "Unknown type"
}
}
fun checkAndPrint(list: List) {
for (item in list) {
if (item is String) {
println("String: ${item.length}")
} else {
println("Not a string")
}
}
}
This code uses smart casts inside when and if to check types and then access properties safely.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping over each item in the list in
checkAndPrint. - How many times: Once for each element in the input list.
Each item in the list is checked once to see if it is a String, then printed accordingly.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 type checks and prints |
| 100 | About 100 type checks and prints |
| 1000 | About 1000 type checks and prints |
Pattern observation: The work grows directly with the number of items; doubling items doubles work.
Time Complexity: O(n)
This means the time to run grows in a straight line with the number of items checked.
[X] Wrong: "Smart casts make the code run faster than just checking types manually, so time complexity is less than linear."
[OK] Correct: Smart casts help with safe access but do not reduce the need to check each item once, so the time still grows with input size.
Understanding how type checks and smart casts affect performance shows you can reason about code efficiency and safety together, a useful skill in real projects.
What if we replaced the for loop with a recursive function? How would the time complexity change?
Practice
if or when block?Solution
Step 1: Understand smart cast purpose
Smart casts let Kotlin automatically treat a variable as a more specific type after you check its type.Step 2: Apply to if/when blocks
Insideiforwhen, Kotlin knows the variable's type and lets you use it without manual casting.Final Answer:
Automatically treats a variable as a specific type after a type check -> Option CQuick Check:
Smart cast = automatic type use after check [OK]
- Thinking manual cast is always needed
- Assuming smart casts disable type checks
- Believing variables convert to string automatically
when expression for variable obj?Solution
Step 1: Check correct when syntax
Thewhenexpression requires parentheses around the variable:when (obj).Step 2: Use type check correctly
The correct type check isis Stringwithout repeating variable name inside the block.Final Answer:
when (obj) { is String -> println(obj.length) else -> println("Not a string") } -> Option DQuick Check:
Correct when syntax uses parentheses andis[OK]
- Omitting parentheses around variable
- Using variable name inside when branches
- Using type name without 'is' keyword
fun test(obj: Any) {
when (obj) {
is String -> println(obj.length)
is Int -> println(obj + 1)
else -> println("Unknown")
}
}
test("Hello")
test(5)
test(3.14)Solution
Step 1: Analyze each call
Fortest("Hello"),objis String, so prints length 5.
Fortest(5),objis Int, so prints 5 + 1 = 6.
Fortest(3.14), no matching type, prints "Unknown".Step 2: Confirm output lines
Outputs are:
5
6
UnknownFinal Answer:
5 6 Unknown -> Option BQuick Check:
Smart cast uses type to choose output [OK]
- Confusing string length with string itself
- Adding 1 to string instead of int
- Expecting default else to print number
fun check(obj: Any) {
if (obj is String) {
println(obj.length)
} else if (obj is Int) {
println(obj + 1)
} else {
println(obj.length)
}
}Solution
Step 1: Review else block usage
In the else block,objcan be any type, but code tries to accessobj.lengthwhich is invalid for non-String types.Step 2: Understand smart cast limits
Smart casts only apply after type checks. Here, no type check before accessinglengthin else block causes error.Final Answer:
Trying to access length on obj in else block without type check -> Option AQuick Check:
Access property only after type check [OK]
- Assuming else block has smart cast automatically
- Confusing else if with when
- Thinking smart casts fail inside if blocks
Any objects, write a Kotlin function using when with smart casts to return a list of strings describing each element's type and value. What is the correct implementation?fun describeList(items: List<Any>): List<String> {
return items.map { item ->
when (item) {
is String -> "String of length ${'$'}{item.length}"
is Int -> "Int with value ${'$'}item"
else -> "Unknown type"
}
}
}Solution
Step 1: Check smart cast usage in when
Thewhenexpression smart castsitemtoStringorIntautomatically after type check.Step 2: Confirm lambda and map usage
Inside the lambda, smart casts work normally, so accessingitem.lengthanditemis valid without explicit casts.Final Answer:
Correct as is, smart casts allow using item.length and item directly -> Option AQuick Check:
Smart casts work inside lambdas and when [OK]
- Adding unnecessary explicit casts
- Thinking smart casts don't work in lambdas
- Replacing when with if-else unnecessarily
Ready to prove it?
Pass the test and this pattern moves unknown
