1. Introduction

To work effectively with Kotlin, knowing how to initialize a List of lists is important. Also known as a two-dimensional array, or a matrix, a list of lists is a data structure that is defined as a single list where each element is, itself, a list.

In this tutorial, we’ll explore several ways to initialize a list of lists in Kotlin.

2. What Is a List of Lists?

In most programming languages, including Kotlin, a list of lists is implemented as a two-dimensional array:

Graphical representation of a List of Lists in Kotlin

In the graphical representation above, the outer list represents the rows and the inner lists represent the columns.

3. Using the listOf() Method

The first approach we’ll explore uses the listOf() method. We can leverage this method to create an immutable list of lists:

@Test
fun `Creates an immutable list of immutable lists using listOf()`() {
    val listOfLists = listOf(listOf(1, 2), listOf(3, 4), listOf(5, 6))

    assertEquals(3, listOfLists.size)
    assertEquals(listOf(1, 2), listOfLists[0])
    assertEquals(listOf(3, 4), listOfLists[1])
    assertEquals(listOf(5, 6), listOfLists[2])
}

In the above unit test, we create a list of three lists, each containing two integers, using the listOf() method. Subsequently, we verify that the list contains exactly three lists and ensure that each inner list contains the correct elements.

listOf() allows us to specify unique values for each sub-list.

4. Using the List Constructor

Another way to initialize a list of lists is by using the List or MutableList constructor, depending on whether we want a mutable or an immutable list:

@Test
fun `Creates an immutable list of mutable lists using List constructor`() {
    val listOfLists = List(3) { MutableList<Int>(2) {0} }
    assertEquals(3, listOfLists.size)
    assertEquals(listOf(0, 0), listOfLists[0])
    assertEquals(listOf(0, 0), listOfLists[1])
    assertEquals(listOf(0, 0), listOfLists[2])
}

Here, we create an immutable list of three empty mutable lists of type Integer. We then assert that there are exactly three inner lists, each with exactly two integers, all of which are zeros.

In contrast to listOf(), using the List Constructor will result in sub-lists with identical items.

5. Using the map() Method

A third way to achieve our goal is by using the map() method. We use this method to create a list containing either mutable or immutable lists, although the parent list we obtain is immutable.

5.1. Creating a List of Immutable Lists

Let’s create a list containing three inner immutable lists using the map() method:

@Test
fun `Creates an immutable list of immutable lists using map method`() {
    val listOfLists = (0..2).map { _ -> (0..1).map { 0 } }

    assertEquals(3, listOfLists.size)
    assertEquals(listOf(0, 0), listOfLists[0])
    assertEquals(listOf(0, 0), listOfLists[1])
    assertEquals(listOf(0, 0), listOfLists[2])
}

First, we create a range of integers from zero to two using the “…” operator and then use the map() method with an anonymous function that accepts an underscore as its parameter and returns another list of two zeros.

Since our outer map() method runs three times, the inner map() function will also run three times and, during each step, will create a sub-list containing two zeros. Lastly, we assert that there are exactly three sub-lists in our list, and each sub-list contains two zeros.

Just like the List constructor, map() constrains us to initialize the sub-lists with identical items.

5.2. Creating a List of MutableLists

Still using the map() method, we can also create a List of MutableLists:

@Test
fun `Creates an immutable list of mutable lists using map method`() {
    val listOfMutableLists = (0..2).map { mutableListOf<Int>() }

    assertEquals(3, listOfMutableLists.size)
    assertTrue(listOfMutableLists.all { it.isEmpty() })
}

6. Conclusion

In this article, we’ve explored various ways of initializing a list of lists in Kotlin.

While some approaches constrain us to initialize each sub-list with identical elements, as is the case with the map() method, others, like the listOf() method, give us control over the value of each individual element.