1. 简介

在 Kotlin 中,Map 是一种存储键值对的数据结构。实际开发中,我们经常需要将 Map 转成字符串,比如用于日志输出、接口返回、数据序列化等场景。

本文将系统介绍几种在 Kotlin 中将 Map 转换为 String 的常用方法,涵盖原生 API 和第三方库方案,帮助你在不同场景下做出合适选择,避免踩坑 ❌。

2. Kotlin 中 Map 转 String 的常见方式

本节将演示多种转换方式。为统一示例,我们先定义一个 User 数据类:

data class User(var firstName: String, var lastName: String)

2.1. 使用 toString() 方法

这是最直接的方式——调用 Map 对象自带的 toString() 方法。Kotlin 默认实现会返回一个格式化的字符串:用花括号包裹,每个键值对之间用逗号加空格分隔,键与值之间用等号连接

✅ 示例代码:

fun `using toString function`(){
    val map = mapOf<Int, User>(
      1 to User("Flore", "P"),
      2 to User("Nappy", "Sean"),
      3 to User("Ndole", "Paul"),
    )

    assertEquals(
        "{1=User(firstName=Flore, lastName=P), 2=User(firstName=Nappy, lastName=Sean), 3=User(firstName=Ndole, lastName=Paul)}", 
        map.toString()
    )
}

⚠️ 注意:输出结果依赖对象自身的 toString() 实现。如果 User 类未重写该方法,可能输出不理想(如内存地址)。建议数据类始终使用 data class,它会自动生成可读性强的 toString()

2.2. 使用 StringBuilder

当需要完全自定义格式时,可以手动遍历 Map 并拼接字符串。这种方式灵活但代码略显冗长。

✅ 示例代码:

@Test
fun `using string builder method`(){
    val map = mapOf<Int, User>(
      1 to User("Flore", "P"),
      2 to User("Nappy", "Sean"),
      3 to User("Ndole", "Paul"),
    )

    val sb = StringBuilder()
    map.forEach { entry ->
        sb.append("${entry.key}=${entry.value} ")
    }
    assertEquals(
        "1=User(firstName=Flore, lastName=P) 2=User(firstName=Nappy, lastName=Sean) 3=User(firstName=Ndole, lastName=Paul) ", 
        sb.toString()
    )
}

📌 适用场景:

  • 需要特殊分隔符(如 & 用于 URL 参数)
  • 只处理部分键值对
  • 想控制前后缀或空格

但注意,频繁字符串拼接性能较差,应优先考虑 joinToString

2.3. 使用 joinToString() 函数

这是推荐的原生方式。joinToString() 是 Kotlin 集合的标准扩展函数,专为集合转字符串设计,语法简洁且高度可配置。

✅ 基础用法:

fun `using joinToString function`(){
    val map = mapOf<Int, User>(
      1 to User("Flore", "P"),
      2 to User("Nappy", "Sean"),
      3 to User("Ndole", "Paul"),
    )

    assertEquals(
        "1=User(firstName=Flore, lastName=P), 2=User(firstName=Nappy, lastName=Sean), 3=User(firstName=Ndole, lastName=Paul)",
        map.entries.joinToString()
    )
    assertEquals(
        "1=User(firstName=Flore, lastName=P)_2=User(firstName=Nappy, lastName=Sean)_3=User(firstName=Ndole, lastName=Paul)", 
        map.entries.joinToString("_")
    )
}

✅ 高级配置:支持前缀、后缀、分隔符、长度限制等:

val map = mapOf<Int, User>(
  1 to User("Flore", "P"),
  2 to User("Nappy", "Sean"),
  3 to User("Ndole", "Paul"),
)

val str = map.entries.joinToString(
  prefix = "[",
  separator = ", ",
  postfix = "]",
  limit = 2,
  truncated = "..."
)
assertEquals(
    "[1=User(firstName=Flore, lastName=P), 2=User(firstName=Nappy, lastName=Sean), ...]",
    str
)

📌 推荐指数:⭐⭐⭐⭐⭐
joinToString 是大多数场景下的首选方案,兼顾可读性与灵活性。

3. 转换为 JSON 字符串

当需要标准化、可跨语言解析的字符串格式时,JSON 是更优选择。以下是两种主流实现方式。

3.1. 使用 JSONObject API

通过 org.json:json 库中的 JSONObjectMap 直接转为 JSON 字符串。该方式简单直接,适合轻量级项目。

📌 添加依赖(Maven):

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20231013</version>
</dependency>

Gradle 用户使用:

implementation 'org.json:json:20231013'

✅ 示例代码:

fun `converting to JSON first`(){
    val map = mapOf<Int, User>(
      1 to User("Flore", "P"),
      2 to User("Nappy", "Sean"),
      3 to User("Ndole", "Paul"),
    )

    val str = JSONObject(map).toString()
    assertEquals(
        """{"1":{"firstName":"Flore","lastName":"P"},"2":{"firstName":"Nappy","lastName":"Sean"},"3":{"firstName":"Ndole","lastName":"Paul"}}""",
        str
    )
}

⚠️ 注意:JSONObject 不支持泛型类型擦除后的复杂对象,若 User 含有嵌套结构需额外处理。

3.2. 使用 Gson

Gson 是 Google 提供的强大 JSON 序列化库,支持泛型、自定义序列化器,广泛用于 Android 和后端服务。

📌 添加依赖:

Gradle:

dependencies {
  implementation 'com.google.code.gson:gson:2.10.1'
}

Maven:

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>

✅ 示例代码:

val map = mapOf<Int, User>(
  1 to User("Flore", "P"),
  2 to User("Nappy", "Sean"),
  3 to User("Ndole", "Paul"),
)
val str1 = Gson().toJson(map).toString()

assertEquals(
    """{"1":{"firstName":"Flore","lastName":"P"},"2":{"firstName":"Nappy","lastName":"Sean"},"3":{"firstName":"Ndole","lastName":"Paul"}}""",
    str1
)

✅ 优势:

  • 自动处理 data class 序列化
  • 支持泛型(配合 TypeToken
  • 可定制字段命名策略(如驼峰转下划线)

📌 推荐指数:⭐⭐⭐⭐⭐
对于需要稳定 JSON 输出的项目,Gson 是生产环境的首选。

4. 总结

方法 适用场景 是否推荐
toString() 快速调试、日志打印 ⚠️ 仅限简单场景
StringBuilder 完全自定义格式 ❌ 除非必要,否则不用
joinToString() 通用字符串拼接 ✅ 强烈推荐
JSONObject 轻量级 JSON 输出 ✅ 小项目可用
Gson 生产环境 JSON 序列化 ✅ 强烈推荐

📌 核心建议:

  • 日常开发优先使用 joinToString()
  • 需要 JSON 格式时,选择 GsonJackson
  • 避免手写拼接,易出错且难维护

所有示例代码均可在 GitHub 获取:https://github.com/Baeldung/kotlin-tutorials/tree/master/core-kotlin-modules/core-kotlin-datastructures


原始标题:Converting a Map to a String in Kotlin