Java 11 中 String trim() 和 strip() 方法的区别
Posted
技术标签:
【中文标题】Java 11 中 String trim() 和 strip() 方法的区别【英文标题】:Difference between String trim() and strip() methods in Java 11 【发布时间】:2018-12-18 09:06:16 【问题描述】:在其他变化中,JDK 11 为 java.lang.String 类引入了 6 个新方法:
repeat(int)
- 按照int
参数提供的次数重复字符串
lines()
- 使用 Spliterator 懒惰地提供源字符串中的行
isBlank()
- 指示字符串是否为空或仅包含空格字符
stripLeading()
- 从开头删除空格
stripTrailing()
- 从末尾删除空格
strip()
- 删除字符串开头和结尾的空格
特别是,strip()
看起来与trim()
非常相似。根据this articlestrip*()
方法的设计目的是:
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.
* ...
*/
这与上面的引用几乎相同。
自 Java 11 以来String.trim()
和 String.strip()
之间到底有什么区别?
【问题讨论】:
【参考方案1】:简而言之:strip()
是 trim()
的“Unicode 感知”演变。含义 trim()
仅删除字符 strip() 删除所有 Unicode 空白字符(但不是所有控制字符,例如 \0)
CSR : JDK-8200378
问题
String::trim 从 Java 早期的 Unicode 开始就存在
尚未完全发展到我们今天广泛使用的标准。
String::trim 使用的空间定义是任意码位少 大于等于空间码点(\u0020),通常称为 作为 ASCII 或 ISO 控制字符。
Unicode 感知修剪例程应该使用 字符::isWhitespace(int)。
此外,开发人员无法专门删除 缩进空格或专门删除尾随白色 空间。
解决方案
引入可识别 Unicode 空白的修剪方法 并提供对仅前导或仅尾随的额外控制。
这些新方法的一个共同特点是,它们使用的“空白”定义与 String.trim()
等旧方法不同(更新)。错误JDK-8200373.
String::trim 的当前 JavaDoc 没有明确说明哪个 代码中使用了“空间”的定义。有额外的 在不久的将来使用不同的修剪方法 空间的定义,澄清是必要的。 String::trim 使用 将空间定义为小于或等于的任何代码点 空格字符代码点 (\u0020.) 较新的修剪方法将 使用(空白)空间的定义作为返回 true 的任何代码点 当传递给 Character::isWhitespace 谓词时。
isWhitespace(char)
方法在 JDK 1.1 中被添加到 Character
,但 isWhitespace(int)
方法直到 JDK 1.5 才被引入到 Character
类中。添加了后一种方法(接受int
类型参数的方法)以支持补充字符。 Character
类的 Javadoc cmets 定义了补充字符(通常使用基于 int 的“代码点”建模)与 BMP 字符(通常使用单个字符建模):
从 U+0000 到 U+FFFF 的字符集有时被称为 作为基本多语言平面(BMP)。代码点的字符 大于 U+FFFF 的称为补充字符。爪哇 平台在 char 数组和 String 和 StringBuffer 类。在此表示中,补充 字符表示为一对 char 值...一个 char 值, 因此,表示基本多语言平面 (BMP) 代码点, 包括 UTF-16 的代理代码点或代码单元 编码。一个 int 值表示所有 Unicode 代码点,包括 补充代码点。 ... 只接受 char 的方法 value 不支持补充字符。 ... 的方法 接受一个 int 值支持所有 Unicode 字符,包括 补充字符。
OpenJDK Changeset.
trim()
和 strip()
之间的基准比较 - Why is String.strip() 5 times faster than String.trim() for blank string In Java 11
【讨论】:
有趣的是符号'\u0000'不是被strip删除,而是被trim删除。 为什么不升级 trim() 本身,而不是创建一个新方法?它会在没有任何开发人员干预的情况下在现有应用程序上工作吗?或者这就是他们决定创建新方法的原因? @human 因为 Java 精神的很大一部分是最大限度地向后兼容。更改String::trim
之类的方法的行为会给现有代码库带来不受欢迎的意外。
strip 的字符世界是 trim 的字符世界的超集吗?换句话说,strip strip 比 trim trim 多吗?
显然 trim 的字符集不是 strip 的子集,因为符号 '\u0000' 不是被 strip 删除,而是被 trim 删除:-/ ...【参考方案2】:
这是一个单元测试,说明了@MikhailKholodkov 使用 Java 11 给出的答案。
(请注意,\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());
【讨论】:
【参考方案3】:一般来说,这两种方法都会从字符串中删除前导和尾随空格。然而,当我们使用 unicode 字符或多语言功能时,区别就来了。
trim() 删除所有前导和尾随字符其 ASCII 值小于或等于 32(“U+0020”或空格)。
根据 Unicode 标准,有各种 ASCII 值大于 32(‘U+0020’)的空格字符。例如:8193(U+2001)。
为了识别这些空格字符,从 Java 1.5 的 Character 类中添加了新方法 isWhitespace(int)。此方法使用 unicode 来识别空格字符。您可以阅读有关 unicode 空格字符的更多信息here。
在 java 11 中添加的新方法条 使用此 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()+"\"");
输出
Before: " String with space "
After trim: " String with space "
After strip: "String with space"
注意:如果您在 windows 机器上运行,由于 unicode 设置有限,您可能无法看到类似的输出。您可以尝试一些在线编译器来测试此代码。
参考:Difference between trim and strip method java
【讨论】:
与其他两个答案有何不同?【参考方案4】:strip() 和 trim() 产生不同输出的示例:
String s = "test string\u205F";
String striped = s.strip();
System.out.printf("'%s'%n", striped);//'test string'
String trimmed = s.trim();
System.out.printf("'%s'%n", trimmed);//'test string '
【讨论】:
以上是关于Java 11 中 String trim() 和 strip() 方法的区别的主要内容,如果未能解决你的问题,请参考以下文章