Różnica między metodami String trim () i strip () w Javie 11

107

JDK 11 wprowadza między innymi 6 nowych metod dla klasy java.lang.String:

  • repeat(int)- Powtarza ciąg tyle razy, ile podano w intparametrze
  • lines() - Używa Spliteratora, aby leniwie podawać linie ze źródła
  • isBlank() - Wskazuje, czy ciąg jest pusty, czy zawiera tylko białe znaki
  • stripLeading() - Usuwa odstępy od początku
  • stripTrailing() - Usuwa spację na końcu
  • strip() - Usuwa białe znaki z początku i końca łańcucha

W szczególności strip()wygląda bardzo podobnie do trim(). Zgodnie z tym artykułem strip*() metody mają na celu:

Metody String.strip (), String.stripLeading () i String.stripTrailing () ograniczają odstępy [określone przez Character.isWhiteSpace ()] z przodu, z tyłu lub z przodu iz tyłu docelowego ciągu.

String.trim() JavaDoc stwierdza:

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

Co jest prawie identyczne z powyższym cytatem.

Jaka jest dokładnie różnica między wersją Java 11 String.trim()i String.strip()od niej?

Michaił Kholodkow
źródło

Odpowiedzi:

106

W skrócie: strip()jest ewolucją plików trim().

CSR: JDK-8200378

Problem

String :: trim istnieje od wczesnych dni Javy, kiedy Unicode nie rozwinął się w pełni do standardu, którego powszechnie używamy dzisiaj.

Definicja przestrzeni używanej przez String :: trim to dowolny punkt kodowy mniejszy lub równy punktowi kodu spacji (\ u0020), powszechnie określany jako znaki sterujące ASCII lub ISO.

Procedury przycinające obsługujące Unicode powinny używać Character :: isWhitespace (int).

Ponadto programiści nie byli w stanie konkretnie usunąć spacji we wcięciach ani w szczególności usunąć spacji końcowej.

Rozwiązanie

Wprowadź metody przycinania, które uwzględniają białe znaki Unicode i zapewniają dodatkową kontrolę tylko na początku lub tylko na końcu.

Wspólną cechą tych nowych metod jest to, że używają innej (nowszej) definicji „białych znaków” niż stare metody, takie jak String.trim(). Błąd JDK-8200373 .

Obecny dokument JavaDoc dla String :: trim nie wyjaśnia, która definicja „spacji” jest używana w kodzie. Ponieważ w najbliższej przyszłości pojawią się dodatkowe metody przycinania, które wykorzystują inną definicję przestrzeni, konieczne jest wyjaśnienie. String :: trim używa definicji spacji jako dowolnego punktu kodowego, który jest mniejszy lub równy punktowi znaku spacji (\ u0020.) Nowsze metody przycinania będą używać definicji (białej) spacji jako dowolnego punktu kodowego, który zwraca wartość true po przekazaniu do Predykat Character :: isWhitespace.

Metoda isWhitespace(char)została dodana Characterw JDK 1.1, ale metoda isWhitespace(int)została wprowadzona do Characterklasy dopiero w JDK 1.5. Druga metoda (przyjmująca parametr typu int) została dodana do obsługi znaków uzupełniających. Komentarze Javadoc dla Characterklasy definiują dodatkowe znaki (zwykle modelowane za pomocą „punktu kodowego” opartego na int) w porównaniu ze znakami BMP (zwykle modelowanymi za pomocą pojedynczego znaku):

Zestaw znaków od U + 0000 do U + FFFF jest czasami nazywany podstawową płaszczyzną wielojęzyczną (BMP). Znaki, których punkty kodowe są większe niż U + FFFF, nazywane są znakami uzupełniającymi. Platforma Java używa reprezentacji UTF-16 w tablicach char oraz w klasach String i StringBuffer. W tej reprezentacji znaki uzupełniające są reprezentowane jako para wartości znaków ... Wartość znaku zatem reprezentuje podstawowe punkty kodowe płaszczyzny wielojęzycznej (BMP), w tym zastępcze punkty kodowe lub jednostki kodowe kodowania UTF-16. Wartość int reprezentuje wszystkie punkty kodowe Unicode, w tym dodatkowe punkty kodowe. ... Metody, które akceptują tylko wartość typu char, nie obsługują znaków uzupełniających. ... Metody akceptujące wartość int obsługują wszystkie znaki Unicode, w tym znaki uzupełniające.

Zestaw zmian OpenJDK .


Porównanie testów porównawczych między trim()i strip()- Dlaczego String.strip () jest 5 razy szybsze niż String.trim () dla pustego ciągu w języku Java 11

Michaił Kholodkow
źródło
7
Ciekawe, że symbol „\ u0000” nie jest usuwany przez pasek, ale usuwany przez przycinanie.
CHEM_Eugene
32

Oto test jednostkowy, który ilustruje odpowiedź @MikhailKholodkov, używając Java 11.

(Zauważ, że \u2000jest powyżej \u0020i nie jest traktowany jako spacja 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());
    }
}
Michaela Wielkanocy
źródło
0

Ogólnie rzecz biorąc, obie metody usuwają spacje wiodące i końcowe z ciągu. Jednak różnica pojawia się, gdy pracujemy z postaciami Unicode lub funkcjami wielojęzycznymi.

trim () usuwa wszystkie początkowe i końcowe znaki, których wartość ASCII jest mniejsza lub równa 32 („U + 0020” lub spacja).

Zgodnie ze standardami Unicode istnieją różne znaki spacji o wartości ASCII większej niż 32 („U + 0020”). Np .: 8193 (U + 2001).

Aby zidentyfikować te znaki spacji, w klasie Character dodano nową metodę isWhitespace (int) z języka Java 1.5. Ta metoda używa Unicode do identyfikacji znaków spacji. Możesz przeczytać więcej o znakach spacji Unicode tutaj .

Nowa metoda strip, która została dodana w java 11, używa tej metody Character.isWhitespace (int) do pokrycia szerokiego zakresu białych znaków i ich usunięcia.

przykład

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

Wynik

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

Uwaga: jeśli pracujesz na komputerze z systemem Windows, możesz nie być w stanie zobaczyć podobnego wyniku z powodu ograniczonego zestawu Unicode. możesz wypróbować kompilatory online do testowania tego kodu.

odniesienie: różnica między metodą przycinania i usuwania java

Rupesh Agrawal
źródło