1. 简介
在实际开发中,经常会遇到需要反转句子中单词顺序的需求。比如将 "hello world"
变成 "world hello"
。这类问题虽然基础,但在字符串处理、编码面试或文本解析场景中非常常见。
Kotlin 提供了多种简洁高效的方式来实现这一功能。本文将带你一步步探索几种主流实现方式,并分析其优劣,方便你在不同场景下做出合适选择。
2. 手动编程实现(循环 + StringBuilder)
我们先从最直观的方式入手:手动遍历单词列表,逐个插入到结果字符串的开头。
目标示例:
输入: "this is a complete sentence"
输出: "sentence complete a is this"
核心思路是使用 split(" ")
拆分句子为单词列表,然后通过 StringBuilder
在每次循环时将当前单词插在前面,从而实现逆序拼接。
fun reverseWordsInSentenceCustomMethod(sentence: String): String {
val words = sentence.split(" ")
val reversedStringBuilder = StringBuilder()
for (word in words) {
reversedStringBuilder.insert(0, "$word ")
}
return reversedStringBuilder.toString().trim()
}
✅ 优点:逻辑清晰,适合初学者理解
⚠️ 缺点:insert(0, ...)
是 O(n) 操作,频繁头插会导致性能下降(整体复杂度接近 O(n²)),不推荐用于长句子
测试用例:
@Test
fun `reverse sentence using programmatic approach`() {
val sentence = "this is a complete sentence"
assertEquals("sentence complete a is this", reverseWordsInSentenceCustomMethod(sentence))
}
💡 踩坑提醒:
StringBuilder.insert(0, ...)
看似简单,实则暗藏性能陷阱。每次插入都要移动后续所有字符,数据量大时会明显拖慢速度。
3. 使用 reversed() 与 joinToString()
更 Kotlin 风格的做法是利用标准库提供的高阶函数组合操作。
fun reverseSentenceUsingReverseAndJoinToStringMethods(sentence: String): String {
val words = sentence.split(" ")
return words.reversed().joinToString(" ")
}
这段代码三步完成:
split(" ")
→ 分割成单词列表.reversed()
→ 返回一个逆序的只读列表(原列表不变).joinToString(" ")
→ 用空格连接成字符串
✅ 优点:
- 代码极简,语义清晰
- 利用了 Kotlin 标准库的函数式特性
- 性能良好,适合大多数场景
⚠️ 注意:reversed()
返回的是 List<T>
,不是原集合类型,但对 String
处理无影响。
测试验证:
@Test
fun `reverse sentence using split and joinToString methods`() {
val sentence = "this is a complete sentence"
assertEquals(
"sentence complete a is this",
reverseSentenceUsingReverseAndJoinToStringMethods(sentence)
)
}
✅ 推荐指数:⭐⭐⭐⭐☆
日常开发首选方案,简洁又高效。
4. 使用 fold 方法
如果你喜欢函数式编程风格,fold
是一个很优雅的选择。
fun reverseSentenceUsingFoldMethod(sentence: String): String {
return sentence.split(" ")
.fold("") { accumulator, word -> "$word $accumulator" }
.trim()
}
📌 工作原理:
- 初始值为空字符串
""
- 每次迭代都将当前
word
放在accumulator
前面 - 最终自然形成逆序字符串
例如:
初始: ""
第一次: "this " + "" → "this "
第二次: "is " + "this " → "is this "
第三次: "a " + "is this " → "a is this "
...
最终: "sentence complete a is this"
✅ 优点:一行搞定,极具函数式美感
⚠️ 注意点:
- 字符串拼接会产生大量中间对象(除非 JVM 优化)
- 结果末尾有多余空格,需
trim()
清理
测试代码:
@Test
fun `reverse sentence using a fold method`() {
val sentence = "this is a complete sentence"
assertEquals("sentence complete a is this", reverseSentenceUsingFoldMethod(sentence))
}
💬 小建议:这种写法很酷,但在团队项目中要谨慎使用,避免新人看不懂。
5. 使用 Stack 数据结构
利用栈(Stack)的 LIFO(后进先出) 特性,也非常适合解决此类问题。
fun reverseWordsInSentenceUsingStack(sentence: String): String {
val stack = Stack<String>()
val words = sentence.split(" ")
for (word in words) {
stack.push(word)
}
val reversedSentence = StringBuilder()
while (!stack.empty()) {
reversedSentence.append("${stack.pop()} ")
}
return reversedSentence.toString().trim()
}
流程如下:
- 分词 →
split(" ")
- 全部入栈 →
push()
- 循环出栈拼接 →
pop()
直到栈空
✅ 优点:
- 逻辑直观,符合“反转”直觉
- 易于扩展(如支持多分隔符、过滤空字符串等)
❌ 缺点:
- 多引入一个中间容器
Stack
,内存开销略高 java.util.Stack
是线程安全的,带同步锁,轻微性能损耗
测试用例:
@Test
fun `reverse sentence using a stack`() {
val sentence = "this is a complete sentence"
assertEquals("sentence complete a is this", reverseWordsInSentenceUsingStack(sentence))
}
⚠️ 替代方案:可用
ArrayDeque
替代Stack
提升性能(非同步、双端队列)
6. 总结
方法 | 代码简洁性 | 性能 | 推荐场景 |
---|---|---|---|
✅ reversed() + joinToString() |
⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐☆ | ✅ 日常开发首选 |
🔁 自定义循环 + StringBuilder | ⭐⭐☆ | ⭐⭐ | ❌ 仅教学用途 |
🌀 fold 函数式写法 |
⭐⭐⭐⭐☆ | ⭐⭐⭐ | 🟡 函数式偏好者 |
📦 使用 Stack |
⭐⭐⭐ | ⭐⭐⭐ | 🟡 教学/面试演示 |
📌 最终建议:
- 生产环境优先使用
words.reversed().joinToString(" ")
- 面试时可展示多种解法体现功底
- 注意边界情况:空字符串、多个空格、null 输入等(本文未覆盖,实际需校验)
所有示例代码及单元测试均已上传至 GitHub:
👉 https://github.com/Baeldung/kotlin-tutorials/tree/master/core-kotlin-modules/core-kotlin-strings-4
你可以 clone 下来直接运行测试,加深理解。