1. 概述

在 Kotlin 中,Map 是一种常用的数据结构,用于处理键值对的关联关系。

本篇教程将介绍如何将 Kotlin 中的 Map 转换为 List,涵盖以下几种常见场景:

  • 将 Map 转换为一个包含键值对的列表;
  • 将 Map 分别转换为两个列表:一个包含所有键,一个包含所有值;
  • 在分离键和值时保持它们之间的对应关系。

我们还会通过代码示例和单元测试验证转换结果的正确性。

2. 示例数据准备

为了便于演示,我们先定义一个 Map 示例,用于后续转换操作:

val DEV_MAP: Map<String, String> = mapOf(
  "Kent" to "Linux",
  "Eric" to "MacOS",
  "Kevin" to "Windows",
  "Michal" to "MacOS",
  "Saajan" to "Linux"
)

这个 Map 表示五位开发者及其主要使用的操作系统。接下来我们将围绕这个 Map 展开转换操作。

3. 转换为一个 List

3.1. 获取 Map.Entry 列表

在 Kotlin 中,map.entries 返回一个包含所有键值对的只读 Set。我们可以通过 toList() 方法将其转换为 List:

val result = DEV_MAP.entries.toList()
assertEquals(DEV_MAP.size, result.size)
result.forEach { entry ->
    assertEquals(DEV_MAP[entry.key], entry.value)
}

✅ 这种方式适合需要保留键值对结构的场景。

3.2. 获取 Pair 列表

Kotlin 中的 map.toList() 方法会直接返回一个由 Pair 组成的列表。例如:

val result = DEV_MAP.toList()
assertEquals(DEV_MAP.size, result.size)
result.forEach { pair ->
    assertEquals(DEV_MAP[pair.first], pair.second)
}

✅ 与 entries.toList() 类似,但返回的是更轻量的 Pair 类型。

4. 转换为两个 List:键列表和值列表

4.1. 无关联关系的键值列表

如果我们只需要分别获取键和值的列表,而不需要保留它们之间的对应关系,可以使用如下方式:

val keyList = DEV_MAP.keys.toList()
val valueList = DEV_MAP.values.toList()

assertThat(keyList).containsExactlyInAnyOrder("Kent", "Eric", "Kevin", "Michal", "Saajan")
assertThat(valueList).containsExactlyInAnyOrder("Linux", "MacOS", "Windows", "MacOS", "Linux")

⚠️ 注意:这种方式不能保证键和值的顺序一致,因此不适合需要保持键值对关系的场景。

4.2. 保持键值对应关系的列表

如果我们希望转换后的 keyList 和 valueList 在相同索引位置上仍保持原始的键值对应关系,可以采用以下方式:

方式一:遍历 Map.entries

val keyList = mutableListOf<String>()
val valueList = mutableListOf<String>()
DEV_MAP.entries.forEach {
    keyList += it.key
    valueList += it.value
}

assertThat(keyList).hasSize(DEV_MAP.size)
assertThat(valueList).hasSize(DEV_MAP.size)

repeat(DEV_MAP.size) { idx ->
    assertEquals(DEV_MAP[keyList[idx]], valueList[idx])
}

✅ 使用 MutableList+= 操作符逐个添加元素,保证顺序一致。

方式二:使用 Pair 和解构声明

val (keyList, valueList) = DEV_MAP.toList().let { kvpList ->
    kvpList.map { it.first } to kvpList.map { it.second }
}

assertThat(keyList).hasSize(DEV_MAP.size)
assertThat(valueList).hasSize(DEV_MAP.size)

repeat(DEV_MAP.size) { idx ->
    assertEquals(DEV_MAP[keyList[idx]], valueList[idx])
}

✅ 更加函数式风格,无需显式初始化列表,通过 let 和解构声明实现。

5. 小结

本文介绍了在 Kotlin 中将 Map 转换为 List 的几种常见方式:

转换方式 结果类型 是否保持键值关系 适用场景
entries.toList() List<Map.Entry> 保留键值结构
toList() List<Pair> 更简洁的键值结构
keys.toList() + values.toList() List<Key> + List<Value> 不关心键值对应
遍历 entries 或使用 Pair 解构 List<Key> + List<Value> 保持键值对应关系

根据具体需求选择合适的转换方式,可以更高效地处理 Map 数据。

完整代码示例可参考 GitHub 仓库


原始标题:Convert Map to List in Kotlin