java 中 trim 方法的实现
源代码如下:
| public String trim() {
int len = value.length;
int st = 0;
char[] val = value; / avoid getfield opcode /
while ((st < len) && (val[st] <= ' ')) {<br /> st++;<br /> }<br /> while ((st < len) && (val[len - 1] <= ' ')) {<br /> len--;<br /> }<br /> return ((st > 0) || (len < value.length)) ? substring(st, len) : this;<br />}
| | —- |
可以看到,在 java 实现中, trim方法截取掉了前后 Unicode 小于等于空格的所有控制字符。具体截取的字符可以参考 unicode 字符列表.
kotlin 中 trim() 方法的实现
|
@kotlin.internal.InlineOnly
public inline fun String.trim(): String = (this as CharSequence).trim().toString()
public fun CharSequence.trim(): CharSequence = trim(Char::isWhitespace)
public inline fun CharSequence.trim(predicate: (Char) -> Boolean): CharSequence {
var startIndex = 0
var endIndex = length - 1
var startFound = false
while (startIndex <= endIndex) {<br /> val index = if (!startFound) startIndex else endIndex<br /> val match = predicate(this[index])
if (!startFound) {<br /> if (!match)<br /> startFound = true<br /> else<br /> startIndex += 1<br /> } else {<br /> if (!match)<br /> break<br /> else<br /> endIndex -= 1<br /> }<br /> }
return subSequence(startIndex, endIndex + 1)<br />}
| | —- |
可以看到,kotlin 中的 trim 方法和 java 中的 trim 方法实现基本差不多,唯一的差别就是匹配的字符规则不一样,在 java 匹配的规则是 <= ‘ ‘, 而 kotlin 中匹配的规则是 Char::isWhitespace。
接下来我们看看 Char::isWhitespace 的具体实现:参考
| String.kt
expect fun Char.isWhitespace(): Boolean
实现在 charJVM.kt
public actual fun Char.isWhitespace(): Boolean = Character.isWhitespace(this) || Character.isSpaceChar(this)
| | —- |
可以看到, 在 String.kt 中只是通过 expect 声明了这个方法,具体实现还是在 charJVM.kt 中。关于 expect 和 actual 的用法可以参考 kotlin 平台相关声明.
而在Charactr 类中,isWhitespace() 和 isSpaceChar()的实现如下:
| public static boolean isWhitespace(char ch) {
return isWhitespace((int)ch);
}
public static boolean isWhitespace(int codePoint) {
return CharacterData.of(codePoint).isWhitespace(codePoint);
}
public static boolean isSpaceChar(char ch) {
return isSpaceChar((int)ch);
}
public static boolean isSpaceChar(int codePoint) {
return ((((1 << Character.SPACE_SEPARATOR) |
(1 << Character.LINE_SEPARATOR) |
(1 << Character.PARAGRAPH_SEPARATOR)) >> getType(codePoint)) & 1)
!= 0;
}
| | —- |
这里 isWhitespace() 和 isSpaceChar() 的实现其实比较复杂,简单介绍一下其区别。
isWhiteSpace()符合下面条件的字符将会返回 true
- It is a Unicode space character ({@code SPACE_SEPARATOR}, {@code LINE_SEPARATOR}, or {@code PARAGRAPH_SEPARATOR}) but is not also a non-breaking space ({@code ‘\u005Cu00A0’}, {@code ‘\u005Cu2007’}, {@code ‘\u005Cu202F’}).
- It is {@code ‘\u005Ct’}, U+0009 HORIZONTAL TABULATION.
- It is {@code ‘\u005Cn’}, U+000A LINE FEED.
- It is {@code ‘\u005Cu000B’}, U+000B VERTICAL TABULATION.
- It is {@code ‘\u005Cf’}, U+000C FORM FEED.
- It is {@code ‘\u005Cr’}, U+000D CARRIAGE RETURN.
- It is {@code ‘\u005Cu001C’}, U+001C FILE SEPARATOR.
- It is {@code ‘\u005Cu001D’}, U+001D GROUP SEPARATOR.
- It is {@code ‘\u005Cu001E’}, U+001E RECORD SEPARATOR.
- It is {@code ‘\u005Cu001F’}, U+001F UNIT SEPARATOR.isSpaceChar()用于检查Unicodei分割符和空格,参考Unicode控制字符,分割符号包括
- U+2028 line separator ,HTML: ,LSEP
U+2029 paragraph separator ,HTML: ,PSEP在 java 中和 kotlin 中,因为 trim 方法中使用到的匹配规则不一样,所以他们对同一个串进行处理之后,结果可能也是不一样的。所以为了保险起见,建议不要使用分别用 java 和 kotlin 语言 trim 之后的字符串在进行比较,可能会得有意料之外的结果。
总结
参考链接
- Unicode控制字符
- kotlin 平台相关声明
- Unicode 字符百科
