1. 概述
本文将介绍在 Kotlin 中比较字符串的几种常用方式,帮助你在实际开发中避免踩坑,写出更健壮的代码。
2. 比较运算符
✅ 结构相等:==
在 Kotlin 中,==
运算符用于判断两个字符串内容是否相等,相当于 Java 中的 equals()
方法。这是最常用的字符串比较方式:
val first = "kotlin"
val second = "kotlin"
val firstCapitalized = "KOTLIN"
assertTrue { first == second } // ✅ true,内容相同
assertFalse { first == firstCapitalized } // ❌ false,大小写不同
⚠️ 引用相等:===
===
用于判断两个变量是否指向同一个对象实例,相当于 Java 中的 ==
(引用比较)。
由于字符串字面量会自动进入字符串常量池,因此相同内容的字符串通常共享同一引用:
assertTrue { first === second } // ✅ true,都指向常量池中的同一对象
但如果你通过构造器显式创建新对象,就会绕过常量池,导致引用不一致:
val third = String("kotlin".toCharArray())
assertTrue { first == third } // ✅ 内容相等
assertFalse { first === third } // ❌ 引用不同,third 是堆上新建的对象
💡 踩坑提醒:不要用
===
判断字符串内容!它只适合特殊场景(如性能敏感或单例校验),日常比较一律用==
。
3. 使用 equals
方法
Kotlin 中的 equals()
方法行为与 ==
完全一致,底层也是调用 String.equals()
:
assertTrue { first.equals(second) } // ✅ true
assertFalse { first.equals(firstCapitalized) } // ❌ false
🔍 忽略大小写的比较
如果需要忽略大小写,可以传入 ignoreCase = true
:
assertTrue { first.equals(firstCapitalized, ignoreCase = true) } // ✅ true
✅ 推荐用法:当你需要明确表达“忽略大小写”意图时,使用
equals(ignoreCase = true)
比toLowerCase().equals()
更清晰、更高效。
4. 使用 compareTo
进行排序比较
compareTo()
用于判断字符串的字典序,返回值含义如下:
0
:两字符串相等(按字典序)- 正数:当前字符串 > 参数字符串
- 负数:当前字符串 < 参数字符串
这类似于做减法:a.compareTo(b)
可理解为 “a - b” 的符号。
assertTrue { first.compareTo(second) == 0 } // ✅ 相等
assertTrue { first.compareTo(firstCapitalized) == 32 } // ✅ 'k' - 'K' = 32(ASCII 差值)
assertTrue { firstCapitalized.compareTo(first) == -32 } // ✅ 反向比较
assertTrue { first.compareTo(firstCapitalized, ignoreCase = true) == 0 } // ✅ 忽略大小写后相等
⚠️ 注意:
compareTo
默认区分大小写,且基于 Unicode 编码值排序。对于国际化应用,建议使用java.text.Collator
处理语言敏感的排序逻辑。
5. 总结
方式 | 用途 | 是否忽略大小写 | 推荐场景 |
---|---|---|---|
== |
内容比较 | 否 | ✅ 日常使用 |
=== |
引用比较 | 不适用 | ❌ 极少使用,仅限特殊优化 |
equals() |
内容比较 | 可选 | ✅ 需要显式控制 ignoreCase 时 |
compareTo() |
字典序比较 | 可选 | ✅ 排序、Comparator 实现 |
✅ 最佳实践总结:
- 普通比较用
==
- 忽略大小写用
.equals(other, ignoreCase = true)
- 排序用
compareTo(ignoreCase = true)
或自定义Comparator
- 避免手动转
toLowerCase()
做比较,性能差且可能出错(如 Turkish Locale 问题)
完整示例代码见:GitHub - Baeldung Kotlin Strings