Mik*_*kov 81 java string trim strip java-11
在其他更改中,JDK 11为java.lang.String类引入了6种新方法:
repeat(int)
- 重复String的次数与int
参数提供的次数相同lines()
- 使用Spliterator延迟提供源字符串中的行isBlank()
- 指示String是否为空或仅包含空格字符stripLeading()
- 从头开始删除空白区域stripTrailing()
- 从末端移除空白区域strip()
- 从字符串的开头和结尾删除空白区域 特别是,strip()
看起来非常相似trim()
.根据这篇文章, strip*()
方法旨在:
String.strip(),String.stripLeading()和String.stripTrailing()方法修剪目标字符串的正面,背面或正面和背面的空白[由Character.isWhiteSpace()确定].
String.trim()
JavaDoc声明:
/**
* Returns a string whose value is this string, with any leading and trailing
* whitespace removed.
* ...
*/
Run Code Online (Sandbox Code Playgroud)
这几乎与上面的引用相同.
究竟之间的差别String.trim()
,并String.strip()
因为Java的11?
Mik*_*kov 84
简而言之:strip()
是"Unicode-aware"的演变trim()
.
问题
String :: trim早在Java早期就存在,当时Unicode还没有完全发展到我们今天广泛使用的标准.
String :: trim使用的空间定义是小于或等于空格代码点(\ u0020)的任何代码点,通常称为ASCII或ISO控制字符.
支持Unicode的修剪例程应该使用Character :: isWhitespace(int).
此外,开发人员无法专门删除缩进空白区域或专门删除尾随空白区域.
解
引入可识别Unicode空白区域的修剪方法,并提供对仅前导或仅尾随的附加控制.
这些新方法的一个共同特点是它们使用与"空白"不同的(更新的)定义,而不是像旧的方法那样String.trim()
.错误JDK-8200373.
String :: trim的当前JavaDoc不清楚代码中使用了"space"的哪个定义.随着在不久的将来使用不同的空间定义的修剪方法,澄清是必要的.String :: trim使用空格的定义作为小于或等于空格字符代码点的任何代码点(\ u0020.)较新的修剪方法将使用(白色)空间的定义作为传递给传递给它时返回true的任何代码点. Character :: isWhitespace谓词.
使用JDK 1.1 isWhitespace(char)
添加了该方法Character
,但直到JDK 1.5才将该方法isWhitespace(int)
引入Character
该类.后一种方法(接受类型参数的方法int
)被添加以支持补充字符.Character
该类的Javadoc注释定义了补充字符(通常使用基于int的"代码点"建模)与BMP字符(通常使用单个字符建模):
从U + 0000到U + FFFF的字符集有时被称为基本多语言平面(BMP).代码点大于U + FFFF的字符称为增补字符.Java平台在char数组和String和StringBuffer类中使用UTF-16表示.在此表示中,补充字符表示为一对char值...因此,char值表示基本多语言平面(BMP)代码点,包括代理代码点或UTF-16编码的代码单元.int值表示所有Unicode代码点,包括补充代码点....仅接受char值的方法不支持补充字符....接受int值的方法支持所有Unicode字符,包括补充字符.
OpenJDK Changeset.
trim()
和之间的基准比较strip()
- 为什么String.strip()比String.trim()快5倍于空白字符串在Java 11中
Mic*_*ter 18
这是一个单元测试,用Java 11来说明@MikhailKholodkov的答案.
(注意\u2000
在上面\u0020
,不考虑空白trim()
)
public class StringTestCase {
@Test
public void testSame() {
String s = "\t abc \n";
assertEquals("abc", s.trim());
assertEquals("abc", s.strip());
}
@Test
public void testDifferent() {
Character c = '\u2000';
String s = c + "abc" + c;
assertTrue(Character.isWhitespace(c));
assertEquals(s, s.trim());
assertEquals("abc", s.strip());
}
}
Run Code Online (Sandbox Code Playgroud)
Rup*_*wal 12
通常,这两种方法都会从字符串中删除前导和尾随空格。然而,当我们使用 unicode 字符或多语言功能时,差异就会出现。
trim() 删除所有ASCII 值小于或等于 32('U+0020' 或空格)的前导和尾随字符。
根据 Unicode 标准,有多种 ASCII 值大于 32('U+0020') 的空格字符。例如:8193(U+2001)。
为了识别这些空格字符,Java 1.5 在 Character 类中添加了新方法 isWhitespace(int)。此方法使用 unicode 来识别空格字符。您可以在此处阅读有关 unicode 空格字符的更多信息。
在 java 11 中添加的新方法 strip使用这个 Character.isWhitespace(int) 方法来覆盖广泛的空白字符并删除它们。
例子
public class StringTrimVsStripTest {
public static void main(String[] args) {
String string = '\u2001'+"String with space"+ '\u2001';
System.out.println("Before: \"" + string+"\"");
System.out.println("After trim: \"" + string.trim()+"\"");
System.out.println("After strip: \"" + string.strip()+"\"");
}
}
Run Code Online (Sandbox Code Playgroud)
输出
Before: " String with space "
After trim: " String with space "
After strip: "String with space"
Run Code Online (Sandbox Code Playgroud)
注意:如果您在 Windows 机器上运行,由于 unicode 设置有限,您可能无法看到类似的输出。您可以尝试一些在线编译器来测试此代码。
小智 7
一个例子,其中strip()
和trim()
results in different output:
String s = "test string\\u205F";\nString striped = s.strip();\nSystem.out.printf("\'%s\'%n", striped);//\'test string\'\n\nString trimmed = s.trim();\nSystem.out.printf("\'%s\'%n", trimmed);//\'test string\xe2\x81\x9f\'\n
Run Code Online (Sandbox Code Playgroud)\n