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

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().

CSR:JDK-8200378

问题

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中

  • 有趣的是符号 '\u0000' 不是被 strip 删除,而是被 trim 删除。 (11认同)
  • @human 因为 Java 精神的一个重要部分是最大化向后兼容性。更改“String::trim”等方法的行为会给现有代码库带来不受欢迎的意外。 (4认同)
  • 为什么不升级trim()本身,而不是创建一个新方法?它可以在现有应用程序上运行而无需任何开发人员干预吗?或者这就是他们决定创建新方法的原因? (2认同)
  • Strip 的角色世界是 Trim 的角色世界的超集吗?换句话说,剥离比修剪更多? (2认同)

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)

  • 我建议您也打印输出。 (4认同)

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 设置有限,您可能无法看到类似的输出。您可以尝试一些在线编译器来测试此代码。

参考: trim和strip方法java的区别

  • 与其他两个答案有何不同? (2认同)

小智 7

一个例子,其中strip()trim() results in different output:

\n
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