A Kotlin Map is a collection interface that represents a group of key-value pairs where each key is unique and maps to exactly one value. Kotlin Map comes in two primary variants: immutable maps (read-only) and mutable maps (modifiable). The Kotlin Map interface provides various methods to access, search, and manipulate data efficiently.
Kotlin Map is particularly useful when you need to establish relationships between data elements, such as storing user preferences, configuration settings, or mapping database records to objects in your Kotlin applications.
An immutable Kotlin Map cannot be modified after creation. Once you create an immutable map, you cannot add, remove, or update its elements.
val immutableMap = mapOf("name" to "John", "age" to 25)
A mutable Kotlin Map allows you to modify its contents after creation. You can add new key-value pairs, remove existing ones, or update values.
val mutableMap = mutableMapOf("name" to "John", "age" to 25)
Kotlin HashMap is a mutable map implementation that uses hash table for storage, providing fast access to elements.
val hashMap = hashMapOf("country" to "USA", "city" to "New York")
LinkedHashMap maintains the insertion order of elements while providing HashMap-like performance.
val linkedHashMap = linkedMapOf("first" to 1, "second" to 2)
SortedMap keeps its elements sorted according to the natural ordering of keys or a custom comparator.
val sortedMap = sortedMapOf("zebra" to 1, "apple" to 2, "banana" to 3)
The mapOf()
function creates an immutable Kotlin Map with specified key-value pairs.
val studentGrades = mapOf(
"Alice" to 95,
"Bob" to 87,
"Charlie" to 92
)
The mutableMapOf()
function creates a mutable Kotlin Map that can be modified after creation.
val inventory = mutableMapOf(
"laptops" to 15,
"phones" to 30,
"tablets" to 8
)
The to
infix function creates Pair objects that can be used to initialize Kotlin Maps.
val colors = mapOf(
"red" to "#FF0000",
"green" to "#00FF00",
"blue" to "#0000FF"
)
You can also use the Pair constructor explicitly to create key-value associations.
val coordinates = mapOf(
Pair("x", 10),
Pair("y", 20),
Pair("z", 30)
)
The get()
method retrieves the value associated with a specific key in the Kotlin Map.
val userInfo = mapOf("username" to "john_doe", "email" to "[email protected]")
val username = userInfo.get("username") // Returns "john_doe"
The index operator provides a convenient way to access map elements using square brackets.
val prices = mapOf("apple" to 1.50, "banana" to 0.75, "orange" to 2.00)
val applePrice = prices["apple"] // Returns 1.50
The getValue()
method returns the value for a key, throwing an exception if the key doesn’t exist.
val settings = mapOf("theme" to "dark", "language" to "english")
val theme = settings.getValue("theme") // Returns "dark"
The getOrDefault()
method returns the value for a key or a default value if the key is not found.
val config = mapOf("timeout" to 30, "retries" to 3)
val maxConnections = config.getOrDefault("maxConnections", 100) // Returns 100
The getOrElse()
method returns the value for a key or executes a lambda function if the key is not found.
val cache = mapOf("user1" to "data1", "user2" to "data2")
val userData = cache.getOrElse("user3") { "default_data" } // Returns "default_data"
The put()
method adds a new key-value pair to a mutable Kotlin Map or updates an existing key’s value.
val shoppingCart = mutableMapOf("bread" to 2, "milk" to 1)
shoppingCart.put("eggs", 12) // Adds eggs with quantity 12
You can use the index operator to add or update elements in a mutable Kotlin Map.
val scores = mutableMapOf("math" to 85, "science" to 90)
scores["history"] = 88 // Adds history with score 88
The putAll()
method adds all key-value pairs from another map to the current mutable Kotlin Map.
val baseConfig = mutableMapOf("debug" to true, "version" to "1.0")
val additionalConfig = mapOf("author" to "Developer", "year" to 2024)
baseConfig.putAll(additionalConfig)
The remove()
method removes a key-value pair from a mutable Kotlin Map.
val todoList = mutableMapOf("task1" to "completed", "task2" to "pending", "task3" to "cancelled")
todoList.remove("task3") // Removes task3 from the map
The clear()
method removes all elements from a mutable Kotlin Map.
val tempData = mutableMapOf("temp1" to 25, "temp2" to 30)
tempData.clear() // Removes all elements
The size
property returns the number of key-value pairs in the Kotlin Map.
val fruits = mapOf("apple" to 5, "banana" to 3, "orange" to 7)
println("Map size: ${fruits.size}") // Output: Map size: 3
The isEmpty()
method checks if the Kotlin Map contains no elements.
val emptyMap = mapOf<String, Int>()
println("Is empty: ${emptyMap.isEmpty()}") // Output: Is empty: true
The isNotEmpty()
method checks if the Kotlin Map contains at least one element.
val dataMap = mapOf("key1" to "value1")
println("Is not empty: ${dataMap.isNotEmpty()}") // Output: Is not empty: true
The keys
property returns a set containing all keys in the Kotlin Map.
val countryCapitals = mapOf("USA" to "Washington", "France" to "Paris", "Japan" to "Tokyo")
val countries = countryCapitals.keys
println("Countries: $countries") // Output: Countries: [USA, France, Japan]
The values
property returns a collection containing all values in the Kotlin Map.
val ageMap = mapOf("Alice" to 25, "Bob" to 30, "Charlie" to 35)
val ages = ageMap.values
println("Ages: $ages") // Output: Ages: [25, 30, 35]
The entries
property returns a set of key-value pairs as Map.Entry objects.
val gradeMap = mapOf("Math" to "A", "Science" to "B", "History" to "A+")
for (entry in gradeMap.entries) {
println("${entry.key}: ${entry.value}")
}
The containsKey()
method checks if a specific key exists in the Kotlin Map.
val inventory = mapOf("widgets" to 100, "gadgets" to 50, "tools" to 25)
val hasWidgets = inventory.containsKey("widgets") // Returns true
The containsValue()
method checks if a specific value exists in the Kotlin Map.
val statusMap = mapOf("server1" to "online", "server2" to "offline", "server3" to "online")
val hasOfflineServer = statusMap.containsValue("offline") // Returns true
The filter()
method creates a new map containing only elements that match a given predicate.
val numbers = mapOf("one" to 1, "two" to 2, "three" to 3, "four" to 4)
val evenNumbers = numbers.filter { it.value % 2 == 0 }
println("Even numbers: $evenNumbers") // Output: Even numbers: {two=2, four=4}
The mapValues()
method creates a new map with the same keys but transformed values.
val prices = mapOf("apple" to 1.0, "banana" to 0.5, "orange" to 1.5)
val discountedPrices = prices.mapValues { it.value * 0.9 }
println("Discounted prices: $discountedPrices")
The mapKeys()
method creates a new map with transformed keys but the same values.
val usernames = mapOf("user1" to "John", "user2" to "Jane", "user3" to "Bob")
val uppercaseKeys = usernames.mapKeys { it.key.uppercase() }
println("Uppercase keys: $uppercaseKeys")
You can iterate over a Kotlin Map using a for loop with the entries property.
val productPrices = mapOf("laptop" to 999.99, "mouse" to 29.99, "keyboard" to 79.99)
for ((product, price) in productPrices) {
println("$product costs $${price}")
}
The forEach()
method executes a lambda function for each key-value pair in the Kotlin Map.
val temperatures = mapOf("Monday" to 25, "Tuesday" to 28, "Wednesday" to 22)
temperatures.forEach { (day, temp) ->
println("$day: ${temp}°C")
}
You can iterate over map keys and access corresponding values.
val studentScores = mapOf("Alice" to 95, "Bob" to 87, "Charlie" to 92)
for (student in studentScores.keys) {
println("$student scored ${studentScores[student]} points")
}
The plus operator creates a new map by combining two maps, with the second map’s values taking precedence for duplicate keys.
val baseSettings = mapOf("theme" to "light", "fontSize" to 12)
val userSettings = mapOf("fontSize" to 14, "notifications" to true)
val mergedSettings = baseSettings + userSettings
println("Merged settings: $mergedSettings")
You can convert a Kotlin Map to a list of pairs using the toList()
method.
val colorCodes = mapOf("red" to "#FF0000", "green" to "#00FF00", "blue" to "#0000FF")
val colorList = colorCodes.toList()
println("Color list: $colorList")
You can convert a list of pairs to a Kotlin Map using the toMap()
method.
val pairList = listOf("name" to "John", "age" to 30, "city" to "New York")
val personMap = pairList.toMap()
println("Person map: $personMap")
The groupBy()
method groups elements by a key selector function.
val words = listOf("apple", "banana", "cherry", "apricot", "blueberry")
val groupedByFirstLetter = words.groupBy { it.first() }
println("Grouped by first letter: $groupedByFirstLetter")
Here’s a comprehensive example demonstrating various Kotlin Map operations in a practical scenario:
import kotlin.collections.*
fun main() {
// Creating different types of maps
println("=== Creating Kotlin Maps ===")
// Immutable map
val studentGrades = mapOf(
"Alice" to 95,
"Bob" to 87,
"Charlie" to 92,
"Diana" to 89,
"Edward" to 76
)
println("Student grades: $studentGrades")
// Mutable map
val inventory = mutableMapOf(
"laptops" to 15,
"phones" to 30,
"tablets" to 8
)
println("Initial inventory: $inventory")
// HashMap
val userProfiles = hashMapOf(
"john_doe" to "John Doe",
"jane_smith" to "Jane Smith",
"bob_johnson" to "Bob Johnson"
)
println("User profiles: $userProfiles")
// LinkedHashMap (maintains insertion order)
val orderedTasks = linkedMapOf(
"morning" to "Exercise",
"afternoon" to "Work",
"evening" to "Dinner",
"night" to "Sleep"
)
println("Ordered tasks: $orderedTasks")
// SortedMap (keeps elements sorted)
val sortedScores = sortedMapOf(
"zebra" to 100,
"apple" to 85,
"banana" to 92
)
println("Sorted scores: $sortedScores")
println("\n=== Accessing Map Elements ===")
// Different ways to access elements
val username = userProfiles["john_doe"]
println("Username: $username")
val aliceGrade = studentGrades.getValue("Alice")
println("Alice's grade: $aliceGrade")
val defaultTimeout = mapOf("retries" to 3).getOrDefault("timeout", 30)
println("Default timeout: $defaultTimeout")
val userData = userProfiles.getOrElse("unknown_user") { "Guest User" }
println("User data: $userData")
println("\n=== Modifying Mutable Maps ===")
// Adding elements
inventory["monitors"] = 12
inventory.put("keyboards", 25)
println("Updated inventory: $inventory")
// Adding multiple elements
val newItems = mapOf("mice" to 40, "webcams" to 18)
inventory.putAll(newItems)
println("Inventory after adding multiple items: $inventory")
// Removing elements
inventory.remove("tablets")
println("Inventory after removing tablets: $inventory")
println("\n=== Map Properties and Operations ===")
// Map properties
println("Student grades size: ${studentGrades.size}")
println("Is inventory empty: ${inventory.isEmpty()}")
println("Is student grades not empty: ${studentGrades.isNotEmpty()}")
// Keys, values, and entries
println("Student names: ${studentGrades.keys}")
println("Grade values: ${studentGrades.values}")
println("Inventory entries:")
for (entry in inventory.entries) {
println(" ${entry.key}: ${entry.value}")
}
// Checking existence
val hasAlice = studentGrades.containsKey("Alice")
println("Has Alice in grades: $hasAlice")
val hasGrade95 = studentGrades.containsValue(95)
println("Has grade 95: $hasGrade95")
println("\n=== Filtering and Transformation ===")
// Filtering
val highGrades = studentGrades.filter { it.value >= 90 }
println("High grades (>=90): $highGrades")
val lowInventory = inventory.filter { it.value < 20 }
println("Low inventory items (<20): $lowInventory")
// Mapping values
val gradePercentages = studentGrades.mapValues { "${it.value}%" }
println("Grade percentages: $gradePercentages")
// Mapping keys
val uppercaseGrades = studentGrades.mapKeys { it.key.uppercase() }
println("Uppercase student names: $uppercaseGrades")
println("\n=== Iteration Examples ===")
// Iterating with destructuring
println("Student grade report:")
for ((student, grade) in studentGrades) {
val status = if (grade >= 90) "Excellent" else if (grade >= 80) "Good" else "Needs Improvement"
println(" $student: $grade ($status)")
}
// Using forEach
println("Inventory report:")
inventory.forEach { (item, quantity) ->
val status = if (quantity > 20) "Well Stocked" else "Low Stock"
println(" $item: $quantity units ($status)")
}
println("\n=== Advanced Operations ===")
// Merging maps
val baseConfig = mapOf("version" to "1.0", "debug" to false)
val userConfig = mapOf("debug" to true, "theme" to "dark")
val finalConfig = baseConfig + userConfig
println("Final configuration: $finalConfig")
// Converting to list and back
val gradeList = studentGrades.toList()
println("Grades as list: $gradeList")
val backToMap = gradeList.toMap()
println("Back to map: $backToMap")
// Grouping operation
val words = listOf("apple", "banana", "cherry", "apricot", "blueberry", "avocado")
val wordGroups = words.groupBy { it.first().uppercaseChar() }
println("Words grouped by first letter: $wordGroups")
// Complex filtering and transformation
val processedGrades = studentGrades
.filter { it.value >= 80 }
.mapValues { entry ->
when {
entry.value >= 95 -> "A+"
entry.value >= 90 -> "A"
entry.value >= 85 -> "B+"
else -> "B"
}
}
println("Letter grades for students with 80+: $processedGrades")
}
Output:
=== Creating Kotlin Maps ===
Student grades: {Alice=95, Bob=87, Charlie=92, Diana=89, Edward=76}
Initial inventory: {laptops=15, phones=30, tablets=8}
User profiles: {bob_johnson=Bob Johnson, john_doe=John Doe, jane_smith=Jane Smith}
Ordered tasks: {morning=Exercise, afternoon=Work, evening=Dinner, night=Sleep}
Sorted scores: {apple=85, banana=92, zebra=100}
=== Accessing Map Elements ===
Username: John Doe
Alice's grade: 95
Default timeout: 30
User data: Guest User
=== Modifying Mutable Maps ===
Updated inventory: {laptops=15, phones=30, tablets=8, monitors=12, keyboards=25}
Inventory after adding multiple items: {laptops=15, phones=30, tablets=8, monitors=12, keyboards=25, mice=40, webcams=18}
Inventory after removing tablets: {laptops=15, phones=30, monitors=12, keyboards=25, mice=40, webcams=18}
=== Map Properties and Operations ===
Student grades size: 5
Is inventory empty: false
Is student grades not empty: true
Student names: [Alice, Bob, Charlie, Diana, Edward]
Grade values: [95, 87, 92, 89, 76]
Inventory entries:
laptops: 15
phones: 30
monitors: 12
keyboards: 25
mice: 40
webcams: 18
Has Alice in grades: true
Has grade 95: true
=== Filtering and Transformation ===
High grades (>=90): {Alice=95, Charlie=92}
Low inventory items (<20): {laptops=15, monitors=12}
Grade percentages: {Alice=95%, Bob=87%, Charlie=92%, Diana=89%, Edward=76%}
Uppercase student names: {ALICE=95, BOB=87, CHARLIE=92, DIANA=89, EDWARD=76}
=== Iteration Examples ===
Student grade report:
Alice: 95 (Excellent)
Bob: 87 (Good)
Charlie: 92 (Excellent)
Diana: 89 (Good)
Edward: 76 (Needs Improvement)
Inventory report:
laptops: 15 units (Low Stock)
phones: 30 units (Well Stocked)
monitors: 12 units (Low Stock)
keyboards: 25 units (Well Stocked)
mice: 40 units (Well Stocked)
webcams: 18 units (Low Stock)
=== Advanced Operations ===
Final configuration: {version=1.0, debug=true, theme=dark}
Grades as list: [(Alice, 95), (Bob, 87), (Charlie, 92), (Diana, 89), (Edward, 76)]
Back to map: {Alice=95, Bob=87, Charlie=92, Diana=89, Edward=76}
Words grouped by first letter: {A=[apple, apricot, avocado], B=[banana, blueberry], C=[cherry]}
Letter grades for students with 80+: {Alice=A+, Bob=B+, Charlie=A, Diana=B}