Diferencia entre los métodos String trim () y strip () en Java 11

103

Entre otros cambios, JDK 11 introduce 6 nuevos métodos para la clase java.lang.String:

  • repeat(int)- Repite la Cadena tantas veces como lo indique el intparámetro
  • lines() - Utiliza un Spliterator para proporcionar líneas de forma perezosa desde la cadena de origen
  • isBlank() - Indica si la cadena está vacía o contiene solo caracteres de espacio en blanco
  • stripLeading() - Elimina el espacio en blanco desde el principio
  • stripTrailing() - Elimina el espacio en blanco del final
  • strip() - Elimina el espacio en blanco del principio y el final de la cadena

En particular, se strip()parece mucho a trim(). Según este artículo, los strip*() métodos están diseñados para:

Los métodos String.strip (), String.stripLeading () y String.stripTrailing () recortan el espacio en blanco [según lo determinado por Character.isWhiteSpace ()] de la parte frontal, posterior o frontal y posterior de la cadena de destino.

String.trim() JavaDoc afirma:

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

Lo cual es casi idéntico a la cita anterior.

¿Cuál es exactamente la diferencia entre String.trim()y String.strip()desde Java 11?

Mikhail Kholodkov
fuente

Respuestas:

105

En resumen: strip()es la evolución "compatible con Unicode" de trim().

CSR: JDK-8200378

Problema

String :: trim ha existido desde los primeros días de Java cuando Unicode no había evolucionado completamente hasta el estándar que usamos ampliamente en la actualidad.

La definición de espacio utilizada por String :: trim es cualquier punto de código menor o igual que el punto de código de espacio (\ u0020), comúnmente conocido como caracteres de control ASCII o ISO.

Las rutinas de recorte compatibles con Unicode deben usar Character :: isWhitespace (int).

Además, los desarrolladores no han podido eliminar específicamente los espacios en blanco de sangría o eliminar específicamente los espacios en blanco finales.

Solución

Introduzca métodos de recorte que tengan en cuenta los espacios en blanco Unicode y proporcionen un control adicional de solo al principio o al final.

Una característica común de estos nuevos métodos es que utilizan una definición diferente (más reciente) de "espacio en blanco" que los métodos antiguos como String.trim(). Error JDK-8200373 .

El JavaDoc actual para String :: trim no aclara qué definición de "espacio" se utiliza en el código. Con métodos de recorte adicionales en un futuro cercano que utilizan una definición diferente de espacio, la aclaración es imperativa. String :: trim usa la definición de espacio como cualquier punto de código que sea menor o igual que el punto de código del carácter de espacio (\ u0020.) Los métodos de recorte más nuevos usarán la definición de espacio (en blanco) como cualquier punto de código que devuelva verdadero cuando se pasa al Carácter :: predicado isWhitespace.

El método isWhitespace(char)se agregó Charactercon JDK 1.1, pero el método isWhitespace(int)no se introdujo en la Characterclase hasta JDK 1.5. El último método (el que acepta un parámetro de tipo int) se agregó para admitir caracteres suplementarios. Los comentarios de Javadoc para la Characterclase definen caracteres suplementarios (típicamente modelados con un "punto de código" basado en int) versus caracteres BMP (típicamente modelados con un solo carácter):

El conjunto de caracteres de U + 0000 a U + FFFF a veces se denomina plano multilingüe básico (BMP). Los caracteres cuyos puntos de código son mayores que U + FFFF se denominan caracteres suplementarios. La plataforma Java utiliza la representación UTF-16 en matrices de caracteres y en las clases String y StringBuffer. En esta representación, los caracteres suplementarios se representan como un par de valores de caracteres ... Un valor de caracteres, por lo tanto, representa puntos de código del plano multilingüe básico (BMP), incluidos los puntos de código sustitutos o unidades de código de la codificación UTF-16. Un valor int representa todos los puntos de código Unicode, incluidos los puntos de código suplementarios. ... Los métodos que solo aceptan un valor char no pueden admitir caracteres suplementarios. ... Los métodos que aceptan un valor int admiten todos los caracteres Unicode, incluidos los caracteres suplementarios.

Conjunto de cambios OpenJDK .


Comparación de referencia entre trim()y strip(): ¿Por qué String.strip () es 5 veces más rápido que String.trim () para cadenas en blanco en Java 11

Mikhail Kholodkov
fuente
6
Es interesante que el símbolo '\ u0000' no se borre por tira, sino que borre por recorte.
CHEM_Eugene
32

Aquí hay una prueba unitaria que ilustra la respuesta de @MikhailKholodkov, usando Java 11.

(Tenga en cuenta que \u2000está arriba \u0020y no se considera un espacio en blanco por 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());
    }
}
Miguel Pascua
fuente
0

En general, ambos métodos eliminan los espacios iniciales y finales de la cadena. Sin embargo, la diferencia surge cuando trabajamos con caracteres Unicode o funciones multilingües.

trim () elimina todos los caracteres iniciales y finales cuyo valor ASCII sea menor o igual a 32 ('U + 0020' o espacio).

Según los estándares Unicode, hay varios caracteres de espacio que tienen un valor ASCII superior a 32 ('U + 0020'). Ej: 8193 (U + 2001).

Para identificar estos caracteres de espacio, se agregó el nuevo método isWhitespace (int) de Java 1.5 en la clase Character. Este método usa unicode para identificar caracteres de espacio. Puede leer más sobre los caracteres de espacio Unicode aquí .

La nueva tira de método que se agrega en java 11 usa este método Character.isWhitespace (int) para cubrir una amplia gama de caracteres de espacio en blanco y eliminarlos.

ejemplo

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

Salida

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

Nota: Si está ejecutando una máquina con Windows, es posible que no pueda ver la salida similar debido al conjunto limitado de Unicode. puede probar algunos compiladores en línea para probar este código.

referencia: Diferencia entre el método de recorte y desforre java

Rupesh Agrawal
fuente