簡體   English   中英

Java 11 中 String trim() 和 strip() 方法的區別

[英]Difference between String trim() and strip() methods in Java 11

在其他變化中,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.
  * ...
  */

這幾乎與上面的引用相同。

自 Java 11 以來String.trim()String.strip()之間到底有什么區別?

簡而言之: strip()trim() “Unicode-aware”演變。

CSR : JDK-8200378

問題

String::trim 從 Java 的早期就已經存在,當時 Unicode 還沒有完全發展到我們今天廣泛使用的標准。

String::trim 使用的空格定義是任何小於或等於空格代碼點 (\ ) 的代碼點,通常稱為 ASCII 或 ISO 控制字符。

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

此外,開發人員無法專門刪除縮進空白或專門刪除尾隨空白。

解決方案

引入可識別 Unicode 空白並提供僅前導或僅尾隨的附加控制的修剪方法。

這些新方法的一個共同特征是,它們使用與舊方法(例如String.trim()不同(更新)的“空白”定義。 錯誤JDK-8200373

String::trim 的當前 JavaDoc 沒有明確說明代碼中使用了哪個“空間”定義。 隨着不久的將來出現使用不同空間定義的其他修剪方法,澄清是必要的。 String::trim 使用空格的定義作為任何小於或等於空格字符代碼點 (\ ) 的代碼點。較新的修剪方法將使用(白色)空格的定義作為任何在傳遞給Character::isWhitespace 謂詞。

isWhitespace(char)方法在 JDK 1.1 中被添加到Character ,但是isWhitespace(int)方法直到 JDK 1.5 才被引入到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變更集


trim()strip()之間的基准比較 - 為什么在 Java 11 中對於空白字符串 String.strip() 比 String.trim() 快 5 倍

這是一個單元測試,它說明了@MikhailKholodkov 使用 Java 11 給出的答案。

(請注意, \ 高於\ 並且不會被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 字符或多語言功能時,差異就會出現。

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

輸出

Before: "  String    with    space  "
After trim: " String    with    space "
After strip: "String    with    space"

注意:如果您在 Windows 機器上運行,由於 unicode 設置有限,您可能無法看到類似的輸出。 您可以嘗試一些在線編譯器來測試此代碼。

參考: trim和strip方法java的區別

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 '

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM