Unterschied zwischen den Methoden String trim () und strip () in Java 11

103

Unter anderem führt JDK 11 6 neue Methoden für die Klasse java.lang.String ein:

  • repeat(int)- Wiederholt den String so oft wie vom intParameter angegeben
  • lines() - Verwendet einen Spliterator, um träge Zeilen aus der Quellzeichenfolge bereitzustellen
  • isBlank() - Gibt an, ob der String leer ist oder nur Leerzeichen enthält
  • stripLeading() - Entfernt den Leerraum von Anfang an
  • stripTrailing() - Entfernt den Leerraum vom Ende
  • strip() - Entfernt den Leerraum sowohl vom Anfang als auch vom Ende der Zeichenfolge

Insbesondere strip()sieht es sehr ähnlich aus trim(). Gemäß diesem Artikel wurden strip*() Methoden entwickelt, um:

Die Methoden String.strip (), String.stripLeading () und String.stripTrailing () schneiden Leerzeichen [wie durch Character.isWhiteSpace () bestimmt] entweder von der Vorder-, Rückseite oder sowohl von der Vorder- als auch von der Rückseite der Zielzeichenfolge ab.

String.trim() JavaDoc gibt an:

/**
  * Returns a string whose value is this string, with any leading and trailing
  * whitespace removed.
  * ...
  */

Welches ist fast identisch mit dem obigen Zitat.

Was genau ist der Unterschied zwischen String.trim()und String.strip()seit Java 11?

Mikhail Kholodkov
quelle

Antworten:

105

Kurzum: strip()Ist "Unicode-fähige" Evolution von trim().

CSR: JDK-8200378

Problem

String :: trim existiert seit den Anfängen von Java, als sich Unicode nicht vollständig zu dem Standard entwickelt hat, den wir heute weit verbreitet haben.

Die von String :: trim verwendete Definition des Leerzeichens ist ein Codepunkt, der kleiner oder gleich dem Leerzeichencodepunkt (\ u0020) ist und üblicherweise als ASCII- oder ISO-Steuerzeichen bezeichnet wird.

Unicode-fähige Trimmroutinen sollten Character :: isWhitespace (int) verwenden.

Darüber hinaus war es Entwicklern nicht möglich, Leerzeichen für Einrückungen oder nachfolgende Leerzeichen speziell zu entfernen.

Lösung

Führen Sie Trimmmethoden ein, die Unicode-Leerzeichen berücksichtigen und eine zusätzliche Kontrolle darüber bieten, ob nur das Führen oder das Nachlaufen erfolgt.

Ein gemeinsames Merkmal dieser neuen Methoden ist, dass sie eine andere (neuere) Definition von "Leerzeichen" verwenden als alte Methoden wie String.trim(). Bug JDK-8.200.373 .

Das aktuelle JavaDoc für String :: trim macht nicht klar, welche Definition von "Leerzeichen" im Code verwendet wird. In naher Zukunft werden zusätzliche Trimmmethoden eingeführt, die eine andere Definition des Raums verwenden. Eine Klärung ist daher unerlässlich. String :: trim verwendet die Definition von Leerzeichen als Codecode, der kleiner oder gleich dem Codepunkt für Leerzeichen (\ u0020) ist. Neuere Trimmmethoden verwenden die Definition von (Leerzeichen) als Codecode, der bei Übergabe an den Wert true zurückgibt Character :: isWhitespace-Prädikat.

Die Methode isWhitespace(char)wurde Charactermit JDK 1.1 hinzugefügt , aber die Methode isWhitespace(int)wurde Charactererst mit JDK 1.5 in die Klasse eingeführt . Die letztere Methode (die einen Parameter vom Typ akzeptiert int) wurde hinzugefügt, um zusätzliche Zeichen zu unterstützen. Die Javadoc-Kommentare für die CharacterKlasse definieren zusätzliche 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 als Zusatzzeichen bezeichnet. Die Java-Plattform verwendet die UTF-16-Darstellung in char-Arrays sowie in den Klassen String und StringBuffer. In dieser Darstellung werden zusätzliche Zeichen als ein Paar von Zeichenwerten dargestellt ... Ein Zeichenwert repräsentiert daher BMP-Codepunkte (Basic Multilingual Plane), einschließlich der Ersatzcodepunkte oder Codeeinheiten der UTF-16-Codierung. Ein int-Wert repräsentiert alle Unicode-Codepunkte, 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 zusätzlicher Zeichen.

OpenJDK- Änderungssatz .


Benchmark-Vergleich zwischen trim()und strip()- Warum ist String.strip () in Java 11 fünfmal schneller als String.trim () für leere Zeichenfolgen?

Mikhail Kholodkov
quelle
6
Interessanterweise wird das Symbol '\ u0000' nicht durch Streifen gelöscht, sondern durch Trimmen.
CHEM_Eugene
31

Hier ist ein Unit-Test, der die Antwort von @MikhailKholodkov unter Verwendung von Java 11 veranschaulicht.

(Beachten Sie, dass dies \u2000oben steht \u0020und von nicht als Leerzeichen betrachtet wird. 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());
    }
}
Michael Ostern
quelle
0

Im Allgemeinen werden bei beiden Methoden führende und nachfolgende Leerzeichen aus der Zeichenfolge entfernt. Der Unterschied ergibt sich jedoch, wenn wir mit Unicode-Zeichen oder mehrsprachigen Funktionen arbeiten.

trim () entfernt alle führenden und nachfolgenden Zeichen, deren 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) aus Java 1.5 in der Zeichenklasse hinzugefügt. Diese Methode verwendet Unicode, um Leerzeichen zu identifizieren. Weitere Informationen zu Unicode-Leerzeichen finden Sie hier .

Der neue Methodenstreifen, der in Java 11 hinzugefügt wird, verwendet diese Character.isWhitespace (int) -Methode, um eine Vielzahl von Leerzeichen abzudecken und zu entfernen.

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"

Hinweis: Wenn Sie auf einem Windows-Computer ausgeführt werden, können Sie die ähnliche Ausgabe möglicherweise nicht sehen, da der Unicode-Satz begrenzt ist. Sie können einige Online-Compiler ausprobieren, um diesen Code zu testen.

Referenz: Unterschied zwischen Trim- und Strip-Methode Java

Rupesh Agrawal
quelle