Java 11 中 String trim() 和 strip() 方法之间的区别

2022-08-31 06:52:16

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

  • repeat(int)- 将字符串重复参数提供的次数int
  • lines()- 使用拆分器懒惰地提供源字符串中的行
  • isBlank()- 指示字符串是否为空或仅包含空格字符
  • 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.
  * ...
  */

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

自 Java 11 以来,它们之间到底有什么区别?String.trim()String.strip()


答案 1

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

企业社会责任 : JDK-8200378

问题

String::trim 从 Java 的早期 Unicode 就已经存在了

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

String::trim 使用的空间定义是小于或等于空间代码点 (\u0020) 的任何码位,通常称为 ASCII 或 ISO 控制字符。

Unicode 感知修剪例程应使用 Character::isWhitespace(int)。

此外,开发人员无法专门删除缩进空格或专门删除尾随空格。

溶液

引入可识别 Unicode 空格的修剪方法,并提供对仅前导或仅尾随的额外控制。

这些新方法的一个共同特征是,它们使用与旧方法(如 .)不同的(较新的)“空格”定义。错误 JDK-8200373String.trim()

当前用于 String::trim 的 JavaDoc 没有明确说明代码中使用的“空间”定义。随着在不久的将来出现使用不同空间定义的其他修剪方法,因此必须进行澄清。String::trim 使用空格的定义作为小于或等于空格字符码位 (\u0020) 的任何码位。较新的修剪方法将使用(空白)空间的定义作为在传递给 Character::isWhitespace 谓词时返回 true 的任何代码点。

该方法随 JDK 1.1 一起添加到中,但直到 JDK 1.5 才将该方法引入该类。后一种方法(接受类型参数的方法)被添加以支持增补字符。该类的 Javadoc 注释定义了增补字符(通常使用基于 int 的“代码点”建模)与 BMP 字符(通常使用单个字符建模):isWhitespace(char)CharacterisWhitespace(int)CharacterintCharacter

从 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.


和 之间的基准测试比较 - 为什么在 Java 11 中,对于空白字符串,String.strip() 比 String.trim() 快 5 倍trim()strip()


答案 2

下面是一个单元测试,它通过使用 Java 11 @MikhailKholodkov来说明答案。

(请注意,\u2000 位于上方,不被视为空格\u0020trim())

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());
    }
}