Bird
Raised Fist0
Kotlinprogramming~10 mins

Null safety in collections in Kotlin - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Null safety in collections
Declare collection
↓
Specify element type
↓
Allow or disallow nulls?
Yes→Collection holds nulls
↓
Null safety enforced
↓
Use collection safely
This flow shows how Kotlin collections can be declared to allow or disallow null elements, enforcing null safety.
Execution Sample
Kotlin
val list1: MutableList<String> = mutableListOf("a", "b")
val list2: MutableList<String?> = mutableListOf("a", null, "b")
val list3: MutableList<String?> = mutableListOf(null, null)
val list4: MutableList<String> = mutableListOf()
This code declares Kotlin lists with and without null elements to show null safety in collections.
Execution Table
StepCode LineActionCollection TypeAllows Null?Content
1val list1: MutableList<String> = mutableListOf("a", "b")Create list1MutableList<String>No["a", "b"]
2val list2: MutableList<String?> = mutableListOf("a", null, "b")Create list2MutableList<String?>Yes["a", null, "b"]
3val list3: MutableList<String?> = mutableListOf(null, null)Create list3MutableList<String?>Yes[null, null]
4val list4: MutableList<String> = mutableListOf()Create list4MutableList<String>No[]
5Access list1[1]Retrieve elementMutableList<String>No"b"
6Access list2[1]Retrieve elementMutableList<String?>Yesnull
7Try to add null to list1Compile errorMutableList<String>NoError: Null not allowed
8Add null to list2AllowedMutableList<String?>Yes["a", null, "b", null]
💡 Execution stops because Kotlin enforces null safety at compile time; adding null to non-null collections is not allowed.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3After Step 4After Step 8
list1uninitialized["a", "b"]["a", "b"]["a", "b"]["a", "b"]["a", "b"]
list2uninitializeduninitialized["a", null, "b"]["a", null, "b"]["a", null, "b"]["a", null, "b", null]
list3uninitializeduninitializeduninitialized[null, null][null, null][null, null]
list4uninitializeduninitializeduninitializeduninitialized[][]
Key Moments - 3 Insights
Why can't we add null to list1 which is List<String>?
Because list1 is declared as List<String>, it does not allow null elements. Kotlin enforces this at compile time, so adding null causes an error (see step 7 in execution_table).
How can list2 hold null values?
list2 is declared as List<String?>, meaning its elements can be String or null. This allows nulls safely, as shown in steps 2 and 8.
What happens if we try to access a null element in list2?
Accessing a null element returns null safely (step 6). Kotlin forces you to handle this possibility to avoid crashes.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the content of list2 after step 8?
A["a", null, "b", null]
B["a", "b", null]
C["a", null, "b"]
D[null, null]
💡 Hint
Check the 'Content' column at step 8 in execution_table.
At which step does Kotlin prevent adding null to a non-null list?
AStep 2
BStep 4
CStep 7
DStep 6
💡 Hint
Look for the 'Compile error' action in execution_table.
According to variable_tracker, what is the value of list3 after step 3?
A["a", null, "b"]
B[null, null]
C[]
D["a", "b"]
💡 Hint
Check the row for list3 under 'After Step 3' in variable_tracker.
Concept Snapshot
Null safety in Kotlin collections:
- Declare collection type with or without nullable elements (e.g., List<String> vs List<String?>)
- Non-null collections disallow null elements at compile time
- Nullable collections allow nulls safely
- Accessing nullable elements requires null checks
- Kotlin enforces these rules to prevent runtime null errors
Full Transcript
This lesson shows how Kotlin handles null safety in collections. Collections can be declared to hold only non-null elements or to allow nulls by using nullable types. For example, List<String> cannot hold nulls, while List<String?> can. The execution table traces creating such lists, accessing elements, and attempts to add nulls. Kotlin prevents adding null to non-null collections at compile time, ensuring safety. Variable tracking shows how collections change over steps. Key moments clarify common confusions about null allowance and access. The visual quiz tests understanding of collection contents and Kotlin's compile-time checks. Overall, Kotlin's null safety in collections helps avoid null pointer errors by design.

Practice

(1/5)
1. What does Kotlin's null safety feature ensure when working with collections like List or Set?
easy
A. It prevents storing null values in collections declared without nullable types.
B. It automatically converts all null values to empty strings in collections.
C. It allows null values in any collection without restrictions.
D. It disables the use of collections if they contain null values.

Solution

  1. Step 1: Understand Kotlin's null safety in collections

    Kotlin distinguishes between nullable and non-nullable types. Collections declared with non-nullable types cannot hold null values.
  2. Step 2: Apply this to collection elements

    If a collection is declared as List<String>, it cannot contain null. To allow null, it must be declared as List<String?>.
  3. Final Answer:

    It prevents storing null values in collections declared without nullable types. -> Option A
  4. Quick Check:

    Null safety = no null in non-nullable collections [OK]
Hint: Non-nullable collections disallow null elements [OK]
Common Mistakes:
  • Assuming all collections allow null by default
  • Confusing null safety with automatic null replacement
  • Thinking null safety disables collections with nulls
2. Which of the following is the correct way to declare a list that can hold nullable integers in Kotlin?
easy
A. val numbers: List<Int> = listOf(1, 2, null)
B. val numbers: List<Int> = listOf(null, null, null)
C. val numbers: List = listOf(1, 2, 3)
D. val numbers: List = listOf(1, 2, null)

Solution

  1. Step 1: Identify nullable type declaration

    To allow null in a list, the element type must be nullable, written as Int?.
  2. Step 2: Check list initialization

    listOf(1, 2, null) is valid only if the list type is List<Int?>. val numbers: List = listOf(1, 2, null) matches this.
  3. Final Answer:

    val numbers: List<Int?> = listOf(1, 2, null) -> Option D
  4. Quick Check:

    Nullable type uses Int? for null elements [OK]
Hint: Use Type? to allow nulls in collections [OK]
Common Mistakes:
  • Declaring list as List<Int> but adding nulls
  • Using List<Int> with null elements causes error
  • Confusing nullable element type with nullable list
3. What will be the output of the following Kotlin code?
val list: List = listOf("apple", null, "banana")
val filtered = list.filterNotNull()
println(filtered)
medium
A. ["apple", null, "banana"]
B. [null]
C. ["apple", "banana"]
D. Compilation error

Solution

  1. Step 1: Understand filterNotNull() behavior

    This function removes all null elements from a collection, returning a list of non-null elements.
  2. Step 2: Apply filterNotNull() on the list

    Original list has "apple", null, "banana". After filtering, only "apple" and "banana" remain.
  3. Final Answer:

    ["apple", "banana"] -> Option C
  4. Quick Check:

    filterNotNull() removes nulls [OK]
Hint: filterNotNull() removes all nulls from collections [OK]
Common Mistakes:
  • Expecting nulls to remain after filterNotNull()
  • Thinking filterNotNull() causes compile error
  • Confusing filterNotNull() with filter()
4. Identify the error in this Kotlin code snippet:
val list: List<Int> = listOf(1, 2, null, 4)
medium
A. The list declaration syntax is incorrect.
B. The list cannot contain null because Int is non-nullable.
C. The listOf function cannot be used with integers.
D. There is no error; the code compiles fine.

Solution

  1. Step 1: Check element type and values

    The list is declared as List<Int>, which means elements cannot be null.
  2. Step 2: Identify the presence of null

    The list contains a null value, which is not allowed for non-nullable types, causing a compilation error.
  3. Final Answer:

    The list cannot contain null because Int is non-nullable. -> Option B
  4. Quick Check:

    Non-nullable list disallows null elements [OK]
Hint: Non-nullable types disallow null values in collections [OK]
Common Mistakes:
  • Assuming null is allowed in List<Int>
  • Thinking listOf syntax is wrong
  • Ignoring Kotlin's null safety rules
5. Given a list of nullable strings 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?
hard
A. items.filterNotNull().associateWith { it.length }
B. items.associateWith { it!!.length }
C. items.associate { it to it.length }
D. items.map { it.length }.toMap()

Solution

  1. Step 1: Remove null values safely

    Use filterNotNull() to exclude null elements before mapping.
  2. Step 2: Create map with strings as keys and lengths as values

    Use associateWith { it.length } on the filtered list to map each string to its length.
  3. Final Answer:

    items.filterNotNull().associateWith { it.length } -> Option A
  4. Quick Check:

    Filter nulls first, then associate [OK]
Hint: Filter nulls before mapping to avoid errors [OK]
Common Mistakes:
  • Using !! operator risking NullPointerException
  • Trying to associate null keys or values
  • Mapping lengths without filtering nulls first
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard