Kotlinlearncs.online LogoJava

Practice with Collections

var petNames = mutableMapOf<String, MutableList<String>>()
petNames["Geoffrey"] = mutableListOf()
petNames["Geoffrey"]!! += "Gracie"
petNames["Geoffrey"]!! += "Xyz"

We’ll pause before moving on to get more practice with Kotlin’s collections—the lists, maps, and sets that are so useful for solving problems. We’ll also learn how we can combine these collections together to build more interesting data structures. Let’s get started!

Nested Collections
Nested Collections

In the past lessons we’ve seen how to create and use several standard Kotlin collections: Lists, Maps, and Sets:

var friends = mutableListOf<String>("you")
friends += "Gracie"
var favoriteIceCreams = mutableMapOf<String, String>("me" to "Peanut Butter Fudge")
favoriteIceCreams["Gracie"] = "Human food yummy"
favoriteIceCreams["Xyz"] = "Yick"

These collections are quite useful on their own! However, they can also be combined to great effect. Let’s see an example.

// Task list example

Lists of Maps of Sets
Lists of Maps of Sets

You can combine Lists, Maps, and Sets in many interesting ways to build data structures to solve problems. You can create Lists of Maps:

var values = mutableListOf<MutableMap<String, String>>()
var entry = mutableMapOf<String, String>()
entry["test"] = "me"
values += entry

Or Sets of Lists:

var first = mutableListOf("test", "me")
var second = mutableListOf<String>()
second += "test"
second += "me"
var set = mutableSetOf<List<String>>()
set += first
set += second
// Because first and second have the same items, adding second does not modify the set

But generally, it’s more common for the top-level data structure to be a Map: Maps of Maps, Maps of Lists, and Maps of Sets. We’ll get some practice working with these on this lesson’s practice and homework problems.

Kotlin Maps and Nullability
Kotlin Maps and Nullability

One thing you may have noticed is that Kotlin’s null checking doesn’t work so well in some cases on maps. For example:

var map = mutableMapOf("test" to 1)
// This should work, but fails
map["test"] += 1

Let’s briefly discuss why this is, and what we can do about it.

var map = mutableMapOf("test" to 1)
// This should work, but fails
map["test"] += 1

Practice Problem Warm-Up
Practice Problem Warm-Up

We’ll spend the rest of the lesson working on some problems that test our understanding of how to nest collections. First, we’re asked to parse a List<String> into a Map<Set<String>>. Let’s do an example of that together, which you can use as a starting point for the practice problem that follows.

// Warm-up for Section Lists to Map
Created By: learncs.online Staff
/ Version: 2022.2.0

Write a method called sectionListsToMap that, given a List of Strings, parses it into a Map<String, MutableSet<String>> as follows. Each String in the passed list contains a comma-separated list of names of people in a discussion section. The first name is the section leader, and the rest are students. Your map should map each section leader to the set of students in their section. No section leader or student will appear twice in the data set.

For example, given the Strings "challen,student1", "ruisong4,student2, student3" and "friendly,student4, student5", your map would have keys "challen", "ruisong4", and "friendly". "challen" would map to a set containing "student1", "ruisong4" would map to a set containing "student2" and "student3", and so on.

A few hints for approaching this problem. First, consider how to use .split and .trim appropriately to parse the input String. You should get this part to work before proceeding. Then consider when you need to create the map and each set, and how to populate them.

You should not need import statements to solve this problem. Rather, create your maps and sets using mutableMapOf() and mutableSetOf() where appropriate.

Homework Warm-Up
Homework Warm-Up

Next let’s discuss how to approach this lesson’s homework problem. This problem is a bit trickier, since we need to determine when to properly insert entries into our Map, and do some String parsing. So let’s discuss how to get started.

// Warm-up for Script Parser

Homework: Script Parser

Created By: learncs.online Staff
/ Version: 2022.2.0

Write a method called parseScript that accepts a single String and returns a Map<String, MutableList<String>>. The passed String contains a script consisting of lines separated by newlines, each with the following format:

Name: Line

For example, here's a simple script:

Geoffrey: What do you think of this homework problem?
Ahmed: it's a bit sus
Geoffrey: I bet they'll be able to figure it out!
Maaheen: We'll be here to help if they need it.

parseScript parses the script and returns a map mapping each character's name to their lines in order. So, for the script above, the map would contain three keys: "Geoffrey", "Ahmed", and "Maaheen". The List<String> for the key "Geoffrey" would contain the Strings "What do you think of this homework problem!" and "I bet they'll be able to figure it out!" The List<String> for the key "Amhed" would contain the String "it's a bit sus".

A few hints for approaching this problem.

You'll want to use .split to parse the passed String into individual lines. All lines will have the format shown above.

You'll also need to use .split to split each line into the name and their line of dialog. You can assume that the character ":" only appears to delimit the name of the rest of the line.

The first time you encounter a character, there will not be an entry in your map for them. So you should check for this, and create the list when appropriate.

There may be extra whitespace around the name or the line of dialogue, so use .trim appropriately.

You should not need to use any import statements to solve this problem. Instead, use mutableMapOf() and mutableListOf() to create mutable maps and lists when needed.

More Practice

Need more practice? Head over to the practice page.