Question

How to Iterate Over a HashMap in Kotlin

kotlinkotlin-extension

Question

How can you iterate over a HashMap in Kotlin?

For example, given a Kotlin map type such as:

typealias HashMap<K, V> = java.util.HashMap<K, V>

what are the common and idiomatic ways to loop through its entries, keys, or values?

Short Answer

By the end of this page, you will understand how to iterate over a HashMap in Kotlin using idiomatic approaches such as looping through entries, keys, and values. You will also see when to use destructuring, forEach, and other common patterns used in real Kotlin codebases.

Concept

In Kotlin, a HashMap is a key-value collection. Each item in the map has:

  • a key used to identify the item
  • a value stored under that key

When people say they want to “iterate over a HashMap,” they usually mean one of these:

  • loop through every key-value pair
  • loop through only the keys
  • loop through only the values

Although HashMap comes from Java, Kotlin provides cleaner and more readable ways to work with it.

A map matters in real programming because it is often used for:

  • configuration settings
  • user data by ID
  • counting occurrences
  • caching values
  • request parameters
  • lookup tables

In Kotlin, the most common way to iterate a map is to loop through its entries or use destructuring directly in a for loop. This is preferred because it is readable and gives direct access to both the key and the value.

Mental Model

Think of a HashMap like a locker room:

  • each key is a locker number
  • each value is what is stored inside that locker

Iterating over the map means walking past all the lockers and checking:

  • the locker numbers only (keys)
  • the contents only (values)
  • or both the number and the contents (entries)

Kotlin makes this easy by letting you open each locker and directly name the two parts:

for ((key, value) in map) {
    println("$key -> $value")
}

That syntax is called destructuring: Kotlin splits each map entry into two variables for you.

Take Quiz

Syntax and Examples

Basic syntax

Iterate over key-value pairs

val scores = hashMapOf(
    "Alice" to 95,
    "Bob" to 87,
    "Charlie" to 91
)

for ((name, score) in scores) {
    println("$name scored $score")
}

This is the most idiomatic Kotlin approach. Each map entry is unpacked into name and score.

Iterate using entries

for (entry in scores.entries) {
    println("${entry.key} scored ${entry.value}")
}

Use this when you want the full entry object.

Iterate over keys only

for (name in scores.keys) {
    println(name)
}

Iterate over values only

for (score in scores.values) {
    println(score)
}

Iterate with forEach

scores.forEach { (name, score) ->
    println("$name scored $score")
}

This is also common in Kotlin, especially in functional-style code.

Another beginner-friendly example

val ages = HashMap<String, Int>()
ages["Maya"] = 24
ages["Noah"] = 29
ages["Liam"] = 31

for ((person, age) in ages) {
    println("$person is $age years old")
}

This loops through every entry and prints both parts clearly.

Step by Step Execution

Consider this example:

val items = hashMapOf(
    "pen" to 2,
    "notebook" to 5
)

for ((name, quantity) in items) {
    println("$name: $quantity")
}

Here is what happens step by step:

  1. A HashMap named items is created.

    • key "pen" has value 2
    • key "notebook" has value 5
  2. The for loop starts:

for ((name, quantity) in items)
  1. Kotlin takes the first entry from the map.

    • name becomes the key
    • quantity becomes the value
  2. The println line runs:

println("$name: $quantity")
  1. Kotlin moves to the next entry and repeats the same process.

Possible output:

pen: 2
notebook: 5

Note: HashMap does not guarantee insertion order, so in some cases the printed order may differ. If order matters, use linkedMapOf() or another ordered map type.

Real World Use Cases

Iterating over maps is common in many real applications.

Configuration settings

val config = mapOf(
    "host" to "localhost",
    "port" to "8080",
    "mode" to "debug"
)

for ((key, value) in config) {
    println("$key = $value")
}

Used for printing or validating settings.

Counting values

val wordCounts = hashMapOf(
    "kotlin" to 3,
    "java" to 2,
    "api" to 5
)

for ((word, count) in wordCounts) {
    println("$word appears $count times")
}

Used in text processing and analytics.

API query parameters

val params = mapOf(
    "page" to "1",
    "sort" to "name"
)

for ((key, value) in params) {
    println("$key=$value")
}

Used when building URLs or request payloads.

User lookup data

val users = hashMapOf(
    101 to "Ava",
    102 to "Ethan"
)

for ((id, name) in users) {
    println("User $id is $name")
}

Used in caching, indexing, and data lookup.

Take Quiz

Real Codebase Usage

In real Kotlin projects, developers usually choose the iteration style based on what they need.

Common patterns

1. Destructuring for readability

for ((key, value) in settings) {
    println("$key -> $value")
}

Best when both parts are needed.

2. Guard clauses while iterating

for ((key, value) in settings) {
    if (value.isBlank()) continue
    println("Valid setting: $key = $value")
}

Useful for skipping invalid entries early.

3. Validation

for ((field, value) in formData) {
    if (value.isBlank()) {
        println("$field is required")
    }
}

Common in forms, API inputs, and configuration loading.

4. Transformation with collection functions

val uppercased = scores.map { (name, score) ->
    "$name: ${score + 1}"
}

In many codebases, developers use map, filter, and forEach instead of a plain loop when transforming data.

5. Error reporting

val errors = mutableMapOf<String, String>()

for ((field, message) in errors) {
    println("Error in $field: $message")
}

Maps are often used to store field names and associated messages.

Idiomatic advice

  • Use for ((k, v) in map) when you need both key and value.
  • Use map.keys or map.values only when you need one side.
  • Use forEach for short operations.
  • Prefer Kotlin collection functions when transforming data instead of printing or mutating inside loops.

Common Mistakes

1. Iterating over keys when you need both key and value

Broken or inefficient approach:

for (key in scores.keys) {
    println("$key -> ${scores[key]}")
}

This works, but it performs a lookup for each key. A clearer approach is:

for ((key, value) in scores) {
    println("$key -> $value")
}

2. Assuming HashMap keeps insertion order

Broken assumption:

val map = hashMapOf("a" to 1, "b" to 2, "c" to 3)
for ((k, v) in map) {
    println(k)
}

Do not rely on the output order. If order matters, use an ordered map.

3. Forgetting that keys may not exist

val age = scores["Unknown"]
println(age)

This may print null. Kotlin maps often return nullable values when a key is missing.

Safer approach:

val age = scores["Unknown"] ?: 0
println(age)

4. Confusing Map and MutableMap

val data: Map<String, Int> = mapOf("a" to 1)
// data["b"] = 2 // Error

If you need to add or change entries, use MutableMap or HashMap.

5. Writing overly Java-like Kotlin

Less idiomatic:

val iterator = scores.entries.iterator()
while (iterator.hasNext()) {
    val entry = iterator.next()
    println(entry.key)
}

More idiomatic Kotlin:

for ((key, value) in scores) {
    println("$key -> $value")
}

Prefer Kotlin-style loops unless you specifically need an iterator.

Comparisons

ApproachExampleBest whenNotes
Iterate over map directlyfor ((k, v) in map)You need both key and valueMost idiomatic Kotlin
Iterate over entriesfor (entry in map.entries)You want the entry objectSlightly more verbose
Iterate over keysfor (k in map.keys)You only need keysAvoid extra lookups if value is also needed
Iterate over valuesfor (v in map.values)You only need valuesClean and simple
Use forEachmap.forEach { (k, v) -> ... }Short actions or functional styleCommon in Kotlin code

HashMap vs ordered maps

Map typeKeeps order?Use when
HashMapNoFast key-value lookup, order does not matter
LinkedHashMapYes, insertion orderYou want predictable iteration order
SortedMap / TreeMapSorted by keyYou need keys in sorted order

for loop vs forEach

StyleExampleAdvantageTrade-off
for loopfor ((k, v) in map)Very readableSlightly more boilerplate
forEachmap.forEach { (k, v) -> ... }ConciseCan be less clear for beginners
Take Quiz

Cheat Sheet

val map = hashMapOf(
    "a" to 1,
    "b" to 2
)

Iterate over key-value pairs

for ((key, value) in map) {
    println("$key -> $value")
}

Iterate with entries

for (entry in map.entries) {
    println(entry.key)
    println(entry.value)
}

Iterate over keys

for (key in map.keys) {
    println(key)
}

Iterate over values

for (value in map.values) {
    println(value)
}

Use forEach

map.forEach { (key, value) ->
    println("$key -> $value")
}

Key rules

  • for ((k, v) in map) is the most idiomatic option.
  • HashMap does not guarantee iteration order.
  • Use LinkedHashMap if order matters.
  • Accessing map[key] may return null.
  • Use keys or values only when you need one side.
  • Prefer MutableMap or HashMap if you need to modify the map.

FAQ

How do I loop through a HashMap in Kotlin?

Use a for loop with destructuring:

for ((key, value) in map) {
    println("$key -> $value")
}

What is the most idiomatic way to iterate over a map in Kotlin?

The most idiomatic approach is usually:

for ((key, value) in map)

It is concise and readable.

Can I iterate over only the keys or only the values?

Yes.

for (key in map.keys) { }
for (value in map.values) { }

Does HashMap preserve insertion order in Kotlin?

No. If you need predictable iteration order, use LinkedHashMap or linkedMapOf().

What does (key, value) mean in a Kotlin for loop?

It is destructuring. Kotlin takes each map entry and splits it into separate key and value variables.

Should I use forEach or a for loop for maps in Kotlin?

Both are valid. Use a for loop for clarity, especially as a beginner. Use forEach when you prefer a shorter functional style.

Can I modify a HashMap while iterating over it?

Be careful. Modifying a collection while iterating can cause problems. If you need to update it, consider collecting changes first or using safe mutation patterns.

Take Quiz

Mini Project

Description

Build a small inventory viewer in Kotlin that stores product names and quantities in a HashMap and prints the data in different ways. This demonstrates how to iterate over entries, keys, and values in a practical program.

Goal

Create a Kotlin program that reads a map of inventory items and displays full entries, product names only, and quantities only.

Requirements

  • Create a HashMap with at least three inventory items
  • Print every item as name -> quantity
  • Print all product names separately
  • Print all quantities separately
Take Quiz

Keep learning

Related questions

View more