1. 概述

在软件开发中,对字符串进行按字母顺序排序是一个常见需求,尤其在数据检索、展示和去重等场景中非常实用。

本文将介绍几种在 Kotlin 中实现字符串字母排序的方法,涵盖不同业务场景和复杂度需求。你会看到从基础排序到自定义规则,再到语法糖优化的完整演进过程,✅ 掌握这些技巧能让你写出更简洁、更具表达力的 Kotlin 代码。

2. 使用 toCharArray() 和 sorted()

最简单直接的方式是借助 Kotlin 标准库提供的高阶函数。核心思路是:
将字符串转为字符数组 → 排序 → 再拼接回字符串。

private fun sortStringWithCharArrayAndSorted(input: String): String {
    return input.toCharArray().sorted().joinToString("")
}
  • toCharArray():把 String 拆成 CharArray
  • sorted():返回一个已排序的 List<Char>
  • joinToString(""):将列表拼接成字符串,无分隔符

⚠️ 注意:sorted() 返回的是不可变列表(List),不是原地排序。

测试验证:

@Test
fun `using toCharArray and then sorted`() {
    val inputString = "laibkcedfgjh"
    assertEquals("abcdefghijkl", sortStringWithCharArrayAndSorted(inputString))
}

输出结果:

[a, b, c, d, e, f, g, h, i, j, k, l]

这个方法适用于大多数基础排序场景,简洁明了,✅ 推荐作为首选方案。

3. 结合 distinct() 去重排序

如果目标不仅是排序,还要去除重复字符,可以在排序后链式调用 distinct()

private fun sortStringWithCharArrayAnddistinct(input: String): String {
    return input.toCharArray().sorted().distinct().joinToString("")
}
  • distinct():去除集合中的重复元素,保持顺序

举个例子,输入 "lakibkcekdghfgjhh",如果不加 distinct(),结果会是:

abcdefgghhhijkkkl

而使用 distinct() 后,输出为:

abcdefghijkl

测试用例:

@Test
fun `using sorted and distinct`() {
    val inputString = "lakibkcekdghfgjhh"
    assertEquals("abcdefghijkl", sortStringWithCharArrayAnddistinct(inputString))
}

✅ 场景建议:当你需要“排序 + 去重”时,这种链式操作非常优雅,避免手动维护 Set 或循环判断。

4. 使用 sortedWith() 和 compareBy() 实现自定义排序

有时候需求更复杂,比如希望先排辅音,再排元音,且各自内部仍保持字母序。这就不能用默认排序了,得上自定义比较器。

Kotlin 提供了 sortedWith() 配合 compareBy() 来实现多级排序逻辑。

private fun sortStringWithtoCharArrayAndCompareBy(input: String): String {
    val vowels = setOf('a', 'e', 'i', 'o', 'u')
    return input.toCharArray().sortedWith(
        compareBy<Char> { it in vowels } // 元音放后面(true > false)
            .thenBy { it }              // 同组内按字母升序
    ).joinToString("")
}

解释一下排序逻辑:

  • compareBy { it in vowels }:返回布尔值,false(辅音)排前面,true(元音)靠后
  • .thenBy { it }:在前一级相同的情况下,按字符本身排序

测试验证:

@Test
fun `using compareBy`() {
    val inputString = "laibkcedfgjh"
    assertEquals("bcdfghjklaei", sortStringWithtoCharArrayAndCompareBy(inputString))
}

输出说明:

  • 辅音部分:b,c,d,f,g,h,j,k,l ✅ 升序
  • 元音部分:a,e,i ✅ 升序
  • 整体:辅音在前,元音在后

⚠️ 踩坑提醒:布尔值排序中 false < true,所以 it in vowels 返回 false 的辅音会排在前面。如果你想要反过来,可以用 !it.inVowels

这个模式非常适合处理复合排序规则,✅ 是 Kotlin 函数式编程的典型优势体现。

5. 使用扩展函数提升可读性

上面的方法都可以封装成 String 的扩展函数,让调用更自然,代码更具表达力。

Kotlin 的扩展函数允许你在不修改原始类的前提下,为其添加新行为。

例如,把第一种排序方式封装成扩展函数:

private fun String.sortAsc(): String = toCharArray().sorted().joinToString("")

之后你就可以像原生方法一样调用它:

"cdbae".sortAsc() // 输出 "abcde"

测试用例:

@Test
fun `simplify toCharArray and sorted with extension`() {
    assertEquals("abcde", "cdbae".sortAsc())
}

✅ 优势总结:

  • 调用更直观,符合 Kotlin 风格
  • 可复用,避免重复写转换逻辑
  • 易于组合,比如后续还可定义 sortDesc()sortUnique()

❌ 注意事项:

  • 扩展函数不能访问私有成员
  • 过度使用可能导致 API 泛滥,建议只封装高频、通用逻辑

6. 总结

本文介绍了多种在 Kotlin 中对字符串进行字母排序的方法:

方法 适用场景 是否去重 是否支持自定义排序
sorted() 基础排序
sorted().distinct() 排序+去重
sortedWith(compareBy(...)) 复杂排序规则 可组合
扩展函数封装 提升代码可读性 可定制 可定制

所有方法都基于 Kotlin 强大的集合操作 API,链式调用清晰流畅。你可以根据实际需求灵活选择。

💡 小贴士:这些技巧不仅适用于 String,也可迁移到其他集合类型处理中,比如 List 按长度+字典序排序等。

文中所有代码示例均已上传至 GitHub:
https://github.com/Baeldung/kotlin-tutorials/tree/master/core-kotlin-modules/core-kotlin-strings-4


原始标题:Sorting a String Alphabetically in Kotlin