Null safety in collections in Kotlin - Time & Space Complexity
When working with collections in Kotlin, null safety helps avoid errors by controlling which elements can be null.
We want to see how checking for nulls in collections affects the time it takes to run the code.
Analyze the time complexity of the following code snippet.
fun countNonNull(items: List): Int {
var count = 0
for (item in items) {
if (item != null) {
count++
}
}
return count
}
This code counts how many non-null strings are in a list that may contain null values.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping through each element in the list once.
- How many times: Exactly once for every item in the list.
As the list gets bigger, the code checks each item one by one.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 checks |
| 100 | About 100 checks |
| 1000 | About 1000 checks |
Pattern observation: The number of operations grows directly with the size of the list.
Time Complexity: O(n)
This means the time to count non-null items grows in a straight line as the list gets bigger.
[X] Wrong: "Checking for nulls inside the loop makes the code slower by a lot."
[OK] Correct: The null check is very quick and happens once per item, so it doesn't change the overall growth pattern.
Understanding how null safety checks affect performance shows you can write safe and efficient Kotlin code, a skill valued in many coding tasks.
"What if we used a nested list of nullable strings instead of a single list? How would the time complexity change?"
Practice
List or Set?Solution
Step 1: Understand Kotlin's null safety in collections
Kotlin distinguishes between nullable and non-nullable types. Collections declared with non-nullable types cannot holdnullvalues.Step 2: Apply this to collection elements
If a collection is declared asList<String>, it cannot containnull. To allownull, it must be declared asList<String?>.Final Answer:
It prevents storingnullvalues in collections declared without nullable types. -> Option AQuick Check:
Null safety = nonullin non-nullable collections [OK]
- Assuming all collections allow null by default
- Confusing null safety with automatic null replacement
- Thinking null safety disables collections with nulls
Solution
Step 1: Identify nullable type declaration
To allownullin a list, the element type must be nullable, written asInt?.Step 2: Check list initialization
listOf(1, 2, null)is valid only if the list type isList<Int?>. val numbers: List = listOf(1, 2, null) matches this.Final Answer:
val numbers: List<Int?> = listOf(1, 2, null) -> Option DQuick Check:
Nullable type usesInt?for null elements [OK]
Type? to allow nulls in collections [OK]- Declaring list as
List<Int>but adding nulls - Using
List<Int>with null elements causes error - Confusing nullable element type with nullable list
val list: List = listOf("apple", null, "banana")
val filtered = list.filterNotNull()
println(filtered)Solution
Step 1: Understand
This function removes allfilterNotNull()behaviornullelements from a collection, returning a list of non-null elements.Step 2: Apply
Original list has "apple", null, "banana". After filtering, only "apple" and "banana" remain.filterNotNull()on the listFinal Answer:
["apple", "banana"] -> Option CQuick Check:
filterNotNull()removes nulls [OK]
- Expecting nulls to remain after filterNotNull()
- Thinking filterNotNull() causes compile error
- Confusing filterNotNull() with filter()
val list: List<Int> = listOf(1, 2, null, 4)
Solution
Step 1: Check element type and values
The list is declared asList<Int>, which means elements cannot benull.Step 2: Identify the presence of
The list contains anullnullvalue, which is not allowed for non-nullable types, causing a compilation error.Final Answer:
The list cannot containnullbecauseIntis non-nullable. -> Option BQuick Check:
Non-nullable list disallows null elements [OK]
- Assuming
nullis allowed inList<Int> - Thinking
listOfsyntax is wrong - Ignoring Kotlin's null safety rules
val items: List = listOf("a", null, "b", null, "c"), how can you create a map where keys are the strings and values are their lengths, excluding null values safely?Solution
Step 1: Remove null values safely
UsefilterNotNull()to excludenullelements before mapping.Step 2: Create map with strings as keys and lengths as values
UseassociateWith { it.length }on the filtered list to map each string to its length.Final Answer:
items.filterNotNull().associateWith { it.length } -> Option AQuick Check:
Filter nulls first, then associate [OK]
- Using !! operator risking NullPointerException
- Trying to associate null keys or values
- Mapping lengths without filtering nulls first
Ready to prove it?
Pass the test and this pattern moves unknown
