[英]Why is String.strip() 5 times faster than String.trim() for blank string In Java 11
[英]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”演變。
問題
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 設置有限,您可能無法看到類似的輸出。 您可以嘗試一些在線編譯器來測試此代碼。
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.