Unterschied zwischen den Methoden String trim() und strip() in Java 11
Lesezeit: 1 Minute
Michail Cholodkow
Neben anderen Änderungen führt JDK 11 6 neue Methoden für die Klasse java.lang.String ein:
repeat(int) – Wiederholt den String so oft wie von angegeben int Parameter
lines() – Verwendet einen Spliterator, um Zeilen aus der Quellzeichenfolge träge bereitzustellen
isBlank() – Gibt an, ob der String leer ist oder nur Leerzeichen enthält
stripLeading() – Entfernt den Leerraum vom Anfang
stripTrailing() – Entfernt den Leerraum am Ende
strip() – Entfernt den Leerraum sowohl am Anfang als auch am Ende der Zeichenfolge
Bestimmtes, strip() sieht sehr ähnlich aus trim(). Gem Dieser Beitragstrip*() Methoden sind darauf ausgelegt:
Die Methoden String.strip(), String.stripLeading() und String.stripTrailing() schneiden Leerzeichen ab [as determined by Character.isWhiteSpace()]
entweder die Vorderseite, die Rückseite oder sowohl die Vorder- als auch die Rückseite des Zielstrings.
String.trim() JavaDoc sagt:
/**
* Returns a string whose value is this string, with any leading and trailing
* whitespace removed.
* ...
*/
Das ist fast identisch mit dem obigen Zitat.
Was genau ist der Unterschied zw String.trim() und String.strip() seit Java11?
Michail Cholodkow
Zusamenfassend: strip() ist eine “Unicode-fähige” Evolution von trim(). Bedeutung trim() entfernt nur Zeichen <= U+0020 (Leerzeichen); strip() entfernt alle Unicode-Leerzeichen (aber nicht alle Steuerzeichen wie \0)
String::trim existiert seit den Anfängen von Java, als Unicode
hatte sich noch nicht vollständig zu dem Standard entwickelt, den wir heute weit verbreitet verwenden.
Die von String::trim verwendete Definition des Leerzeichens ist jeder Codepunkt kleiner oder gleich dem Leerzeichencodepunkt (\u0020), der allgemein als ASCII- oder ISO-Steuerzeichen bezeichnet wird.
Darüber hinaus waren Entwickler nicht in der Lage, Einrückungsleerzeichen oder nachgestellte Leerzeichen spezifisch zu entfernen.
Lösung
Führen Sie Trimmmethoden ein, die Unicode-Leerzeichen berücksichtigen und zusätzliche Kontrolle über nur führende oder nur nachfolgende Elemente bieten.
Ein gemeinsames Merkmal dieser neuen Methoden ist, dass sie eine andere (neuere) Definition von “Leerraum” verwenden als alte Methoden wie z String.trim(). Insekt JDK-8200373.
Das aktuelle JavaDoc für String::trim macht nicht deutlich, welche Definition von “Leerzeichen” im Code verwendet wird. Da in naher Zukunft weitere Trimmmethoden hinzukommen, die eine andere Raumdefinition verwenden, ist eine Klärung zwingend erforderlich. String::trim verwendet die Definition von Leerzeichen als jeden Codepunkt, der kleiner oder gleich dem Leerzeichen-Codepunkt (\u0020) ist. Neuere Trimmmethoden verwenden die Definition von (Leer-)Leerzeichen als jeden Codepunkt, der wahr zurückgibt, wenn er an übergeben wird Character::isWhitespace-Prädikat.
Die Methode isWhitespace(char) wurde hinzugefügt Character mit JDK 1.1, aber die Methode isWhitespace(int) wurde nicht eingeführt Character Klasse bis JDK 1.5. Die letztere Methode (diejenige, die einen Parameter vom Typ akzeptiert int) wurde hinzugefügt, um ergänzende Zeichen zu unterstützen. Die Javadoc-Kommentare für die Character Klasse definieren ergänzende Zeichen (normalerweise mit int-basiertem “Codepunkt” modelliert) im Vergleich zu BMP-Zeichen (normalerweise mit einem einzelnen Zeichen modelliert):
Der Zeichensatz von U+0000 bis U+FFFF wird manchmal als Basic Multilingual Plane (BMP) bezeichnet. Zeichen, deren Codepunkte größer als U+FFFF sind, werden ergänzende Zeichen genannt. Die Java-Plattform verwendet die UTF-16-Darstellung in Char-Arrays und in den Klassen String und StringBuffer. In dieser Darstellung werden ergänzende Zeichen als ein Paar Zeichenwerte dargestellt … Ein Zeichenwert repräsentiert daher BMP-Codepunkte (Basic Multilingual Plane), einschließlich der Ersatzcodepunkte, oder Codeeinheiten der UTF-16-Codierung. Ein int-Wert stellt alle Unicode-Codepunkte dar, einschließlich zusätzlicher Codepunkte. … Die Methoden, die nur einen Zeichenwert akzeptieren, können keine zusätzlichen Zeichen unterstützen. … Die Methoden, die einen int-Wert akzeptieren, unterstützen alle Unicode-Zeichen, einschließlich ergänzender Zeichen.
Benchmark-Vergleich zw trim() und strip() – Warum ist String.strip() 5-mal schneller als String.trim() für leere Zeichenfolgen in Java 11
Interessant, dass das Symbol ‘\u0000’ nicht per Strip, sondern per Trim gelöscht wird.
– CHEM_Eugen
5. April 2019 um 7:20 Uhr
Warum nicht trim() selbst aktualisieren, anstatt eine neue Methode zu erstellen? Es hätte ohne Entwicklereingriff an bestehenden Anwendungen funktioniert? Oder haben sie sich gerade deshalb entschieden, eine neue Methode zu entwickeln?
– Mensch
4. November 2020 um 12:35 Uhr
@human Weil ein großer Teil des Java-Ethos darin besteht, die Abwärtskompatibilität zu maximieren. Ändern des Verhaltens einer Methode wie z String::trim würde unwillkommene Überraschungen für bestehende Codebasen bringen.
– Basilikum Bourque
6. Dezember 2020 um 8:25 Uhr
Ist das Charakteruniversum von Strip eine Obermenge des Charakteruniversums von Trim? Mit anderen Worten: Entfernt Streifen mehr als Zierleisten?
– Dojo
17. April 2021 um 4:32 Uhr
Anscheinend ist der Zeichensatz von trim keine Teilmenge von strip, da das Symbol ‘\u0000’ nicht von strip gelöscht wird, sondern von trim :-/ …
– Andy
7. Juli 2021 um 11:53 Uhr
Michael Ostern
Hier ist ein Komponententest, der die Antwort von @MikhailKholodkov unter Verwendung von Java 11 veranschaulicht.
(Beachten Sie, dass \u2000 befindet sich über \u0020 und nicht als Leerzeichen betrachtet 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());
}
}
Im Allgemeinen entfernen beide Methoden führende und nachgestellte Leerzeichen aus der Zeichenfolge. Der Unterschied kommt jedoch, wenn wir mit Unicode-Zeichen oder mehrsprachigen Funktionen arbeiten.
trim() entfernt alle führenden und abschließenden Zeichen dessen ASCII-Wert kleiner oder gleich 32 ist (‘U+0020’ oder Leerzeichen).
Gemäß Unicode-Standards gibt es verschiedene Leerzeichen mit einem ASCII-Wert von mehr als 32(‘U+0020’). Beispiel: 8193(U+2001).
Um diese Leerzeichen zu identifizieren, wurde die neue Methode isWhitespace(int) von Java 1.5 in der Character-Klasse hinzugefügt. Diese Methode verwendet Unicode, um Leerzeichen zu identifizieren. Sie können mehr über Unicode-Leerzeichen lesen Hier.
Neuer Methodenstreifen, der in Java 11 hinzugefügt wird Verwenden Sie diese Character.isWhitespace(int)-Methode, um eine breite Palette von Leerzeichen abzudecken und entfernen Sie sie.
Beispiel
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()+"\"");
}
}
Ausgabe
Before: " String with space "
After trim: " String with space "
After strip: "String with space"
Notiz: Wenn Sie auf einem Windows-Computer arbeiten, können Sie die ähnliche Ausgabe aufgrund des begrenzten Unicode-Satzes möglicherweise nicht sehen. Sie können einige Online-Compiler zum Testen dieses Codes ausprobieren.