163

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

  • repeat(int)int- 根据参数提供的多次重复字符串
  • lines()- 使用 Spliterator 懒惰地提供源字符串中的行
  • 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.
  * ...
  */

这几乎与上面的报价相同。

String.trim()Java 11和自 Java 11 以来到底有什么区别String.strip()

4

4 回答 4

172

简而言之:strip()trim(). 含义trim()仅删除字符 <= U+0020(空格);strip()删除所有 Unicode 空白字符(但不是所有控制字符,例如 \0)

企业社会责任:JDK-8200378

问题

String::trim 从 Java 早期就已经存在,当时 Unicode

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

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

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

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

解决方案

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

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

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

JDK 1.1isWhitespace(char)添加了该方法,但直到 JDK 1.5 才将该方法引入该类。添加了后一种方法(接受 type 参数的方法)以支持补充字符。该类的 Javadoc 注释定义了补充字符(通常使用基于 int 的“代码点”建模)与 BMP 字符(通常使用单个字符建模):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变更集


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

于 2018-07-10T13:28:54.440 回答
49

这是一个单元测试,说明了@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());
    }
}
于 2018-08-30T23:43:42.323 回答
17

一般来说,这两种方法都会从字符串中删除前导空格和尾随空格。然而,当我们使用 unicode 字符或多语言功能时,区别就来了。

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

根据 Unicode 标准,有各种 ASCII 值大于 32('U+0020')的空格字符。例如:8193(U+2001)。

为了识别这些空格字符,从 Java 1.5 的 Character 类中添加了新方法 isWhitespace(int)。此方法使用 unicode 来识别空格字符。您可以在此处阅读有关 unicode 空格字符的更多信息。

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

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

于 2020-07-10T14:48:58.517 回答
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 '
于 2021-07-08T06:50:46.367 回答