Java11中 String 镶边()和 Strip ()方法的区别

在其他变化中,JDK 11为 java.lang 引入了6个新方法.String 类:

  • repeat(int)-按照 int参数提供的次数重复字符串
  • lines()-使用 Spliterator 延迟地从源字符串提供行
  • isBlank()-指示字符串是空的还是只包含空白字符
  • 从开始移除空白
  • 从结尾移除空白
  • strip() -删除字符串开头和结尾的空白

特别是,strip()看起来非常类似于 trim():

Strip ()、 String.stripled ()和 String.stripTraining () 方法修剪空白[由 Charter.isWhiteSpace ()确定] 从正面,背面,或者从正面和背面射击目标 绳子。

String.trim() JavaDoc 声明:

/**
* Returns a string whose value is this string, with any leading and trailing
* whitespace removed.
* ...
*/

这几乎与上面的引用完全相同。

从 Java11开始,String.trim()String.strip()到底有什么不同?

79622 次浏览

简而言之: strip()trim()的“ Unicode 感知”演变。意味着 trim()只删除 < = U + 0020(空格)字符; strip()删除所有 Unicode 空格字符(但不是所有控制字符,如0)

企业社会责任: JDK-8200378

问题

从早期的 Java 时代 Unicode 就已经存在了

还没有完全发展到我们今天广泛使用的标准。

装饰所使用的空间的定义是任何代码点少 空间编码点(u0020) ,通常指 作为 ASCII 或 ISO 控制字符。

可识别 Unicode 的修整例程应该使用 字符: : isWhitespace (int)。

此外,开发人员还不能明确删除 缩进空白或专门删除尾随的空白 空间。

解决方案

介绍可识别 Unicode 空白的修剪方法 并提供额外的控制只引导或只跟踪。

这些新方法的一个共同特点是,它们使用了与旧方法(如 String.trim())不同的(较新的)“空白”定义。窃听器 JDK-8200373

当前的 JavaDoc for String: : trim 并没有明确指出是哪一个 “空间”的定义正在代码中使用 在不久的将来,修剪方法将使用不同的 空间的定义,澄清是必要的 将空间定义为任何小于或等于 空格字符编码(u0020)。较新的修剪方法将 使用(空白)空间的定义作为任何返回 true 的代码点 当传递到字符: : 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 的字符称为补充字符 平台使用字符数组中的 UTF-16表示和 字符串和 StringBuffer 类 字符被表示为一对字符值, 因此,表示基本多语言平面(BMP)代码点, 包括代理代码点,或 UTF-16的代码单元 Int 值表示所有 Unicode 代码点,包括 只接受 char 的方法 值不能支持补充字符。 .. 接受 int 值支持所有 Unicode 字符,包括 辅助字符。

OpenJDK 更改设置.


trim()strip()-为什么在 Java11中,对于空白字符串,String.Strip ()比 String.trim ()快5倍的基准比较

下面是一个单元测试,它说明了@MikhailKholdkov 使用 Java11给出的答案。

(请注意,\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());
}
}

通常,这两种方法都从字符串中删除前导空格和尾随空格。然而,当我们使用 Unicode 字符或多语言特性时,差异就出现了。

饰()删除所有前导字符和尾随字符 其 ASCII 值小于或等于32的(“ U + 0020”或空格)。

根据 Unicode 标准,ASCII 值大于32(‘ U + 0020’)的空格字符有很多,Ex: 8193(U + 2001)。

为了识别这些空格字符,我们从 Java 1.5添加了一个新的方法 isWhitespace (int)。此方法使用 unicode 来标识空格字符。您可以阅读有关 Unicode 空格字符 给你的更多信息。

在 java11使用这个 Charter.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 集有限,您可能无法看到类似的输出。您可以尝试一些联机编译器来测试此代码。

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 '