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 高于 \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());
    

【讨论】:

【参考方案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() 方法的区别的主要内容,如果未能解决你的问题,请参考以下文章

java中string.trim()函数的作用

java中trim()函数是什么

java中String的.trim()方法

java.lang.String里面的trim()方法——删除首尾空格

11.为String类扩展trim方法

java —— String 类