Differenza tra i metodi String trim () e strip () in Java 11


103

Tra le altre modifiche, JDK 11 introduce 6 nuovi metodi per la classe java.lang.String:

  • repeat(int) - Ripete la stringa tante volte quante sono fornite dal int parametro
  • lines() - Utilizza uno spliterator per fornire pigramente linee dalla stringa di origine
  • isBlank() - Indica se la stringa è vuota o contiene solo spazi vuoti
  • stripLeading() - Rimuove lo spazio bianco dall'inizio
  • stripTrailing() - Rimuove lo spazio bianco dalla fine
  • strip() - Rimuove lo spazio bianco sia dall'inizio che dalla fine della stringa

In particolare, strip()sembra molto simile a trim(). Come da questo articolo, i strip*() metodi sono progettati per:

I metodi String.strip (), String.stripLeading () e String.stripTrailing () eliminano lo spazio bianco [come determinato da Character.isWhiteSpace ()] dalla parte anteriore, posteriore o anteriore e posteriore della stringa di destinazione.

String.trim() JavaDoc afferma:

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

Che è quasi identico alla citazione sopra.

Qual è esattamente la differenza tra String.trim()e String.strip()da Java 11?

Risposte:


105

In breve: strip()è l'evoluzione "Unicode-aware" di trim().

CSR: JDK-8200378

Problema

String :: trim è esistito fin dai primi giorni di Java, quando Unicode non si era completamente evoluto allo standard che ampiamente usiamo oggi.

La definizione di spazio utilizzata da String :: trim è qualsiasi punto di codice inferiore o uguale al punto di codice spazio (\ u0020), comunemente indicato come caratteri di controllo ASCII o ISO.

Le routine di trimming compatibili con Unicode dovrebbero utilizzare Character :: isWhitespace (int).

Inoltre, gli sviluppatori non sono stati in grado di rimuovere in modo specifico lo spazio vuoto di rientro o di rimuovere in modo specifico lo spazio vuoto finale.

Soluzione

Introdurre metodi di trimming che riconoscono lo spazio vuoto Unicode e forniscono un controllo aggiuntivo solo iniziale o solo finale.

Una caratteristica comune di questi nuovi metodi è che utilizzano una definizione diversa (più recente) di "spazi bianchi" rispetto ai vecchi metodi come String.trim(). Bug JDK-8200373 .

L'attuale JavaDoc per String :: trim non rende chiaro quale definizione di "spazio" viene utilizzata nel codice. Con metodi di rifilatura aggiuntivi in ​​arrivo nel prossimo futuro che utilizzano una diversa definizione di spazio, il chiarimento è imperativo. String :: trim utilizza la definizione di spazio come qualsiasi punto di codice che è minore o uguale al punto di codice del carattere di spazio (\ u0020.) I metodi di taglio più recenti useranno la definizione di spazio (bianco) come qualsiasi punto di codice che restituisce true quando viene passato al Character :: predicato isWhitespace.

Il metodo è isWhitespace(char)stato aggiunto Charactercon JDK 1.1, ma il metodo isWhitespace(int)non è stato introdotto nella Characterclasse fino a JDK 1.5. L'ultimo metodo (quello che accetta un parametro di tipo int) è stato aggiunto per supportare i caratteri supplementari. I commenti Javadoc per la Characterclasse definiscono caratteri supplementari (tipicamente modellati con "code point" basato su int) rispetto ai caratteri BMP (tipicamente modellati con un singolo carattere):

Il set di caratteri da U + 0000 a U + FFFF viene talvolta definito BMP (Basic Multilingual Plane). I caratteri i cui punti di codice sono maggiori di U + FFFF sono chiamati caratteri supplementari. La piattaforma Java utilizza la rappresentazione UTF-16 negli array di caratteri e nelle classi String e StringBuffer. In questa rappresentazione, i caratteri supplementari sono rappresentati come una coppia di valori char ... Un valore char, quindi, rappresenta i punti di codice BMP (Basic Multilingual Plane), inclusi i punti di codice surrogati o le unità di codice della codifica UTF-16. Un valore int rappresenta tutti i punti di codice Unicode, inclusi i punti di codice supplementari. ... I metodi che accettano solo un valore char non possono supportare caratteri supplementari. ... I metodi che accettano un valore int supportano tutti i caratteri Unicode, inclusi i caratteri supplementari.

Set di modifiche OpenJDK .


Confronto benchmark tra trim()e strip(): perché String.strip () è 5 volte più veloce di String.trim () per una stringa vuota in Java 11


6
Interessante che il simbolo "\ u0000" non venga cancellato dalla striscia, ma cancellato dal taglio.
CHEM_Eugene

32

Ecco uno unit-test che illustra la risposta di @MikhailKholodkov, utilizzando Java 11.

(Nota che \u2000è sopra \u0020e non è considerato uno spazio vuoto da 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());
    }
}

0

In generale entrambi i metodi rimuovono gli spazi iniziali e finali dalla stringa. Tuttavia la differenza arriva quando lavoriamo con caratteri Unicode o funzionalità multilingue.

trim () rimuove tutti i caratteri iniziali e finali il cui valore ASCII è minore o uguale a 32 ('U + 0020' o spazio).

Secondo gli standard Unicode ci sono vari caratteri di spazio con un valore ASCII maggiore di 32 ('U + 0020'). Es: 8193 (U + 2001).

Per identificare questi caratteri spazio, è stato aggiunto il nuovo metodo isWhitespace (int) da Java 1.5 nella classe Character. Questo metodo utilizza Unicode per identificare i caratteri dello spazio. Puoi leggere di più sui caratteri dello spazio Unicode qui .

Il nuovo metodo strip che viene aggiunto in java 11 utilizza questo metodo Character.isWhitespace (int) per coprire un'ampia gamma di caratteri di spazio bianco e rimuoverli.

esempio

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

Produzione

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

Nota: se stai utilizzando un computer Windows, potresti non essere in grado di vedere l'output simile a causa del set unicode limitato. puoi provare alcuni compilatori online per testare questo codice.

riferimento: differenza tra il metodo di taglio e striscia java

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.