Разница между методами String trim() и strip() в Java 11

Среди других изменений JDK 11 представляет 6 новых методов для класса java.lang.String:

  • repeat(int) - Повторяет строку столько раз, сколько int параметром int
  • lines() - использует Spliterator, чтобы лениво предоставлять строки из исходной строки
  • isBlank() - Указывает, является ли строка пустой или содержит только пробелы
  • stripLeading() - Удаляет stripLeading() пространство с самого начала
  • stripTrailing() - Удаляет stripTrailing() пространство с конца
  • strip() - Удаляет пустое пространство с обоих, начиная и с конца строки

В частности, strip() выглядит очень похоже на trim(). В соответствии с этой статьей методы strip*() предназначены для:

Методы String.strip(), String.stripLeading() и String.stripTrailing() обрезают белое пространство [, как определено Character.isWhiteSpace()] либо спереди, сзади, либо спереди, и сзади целевой строки.

String.trim() JavaDoc:

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

Это почти идентично приведенной выше цитате.

Какая разница между String.trim() и String.strip() с Java 11?

Ответ 1

Короче говоря: strip() - это эволюция trim() учетом Unicode.

CSR: JDK-8200378

проблема

String :: trim существует с ранних дней Java, когда Unicode не полностью эволюционировал до стандарта, который мы широко используем сегодня.

Определение пространства, используемого String :: trim, - это любая кодовая точка, меньшая или равная кодовой точке пробела (\ u0020), обычно называемая управляющими символами ASCII или ISO.

Процедуры обрезки с учетом Unicode должны использовать Character :: isWhitespace (int).

Кроме того, разработчики не смогли специально удалить пробелы в отступах или удалить пробелы в конце.

Решение

Ввести методы обрезки, учитывающие пробелы в Unicode и обеспечивающие дополнительный контроль только перед или только за трейлингом.

Общей характеристикой этих новых методов является то, что они используют другое (более новое) определение "пробела", чем старые методы, такие как String.trim(). Ошибка JDK-8200373.

Текущий JavaDoc для String :: trim не проясняет, какое определение "пробела" используется в коде. В ближайшем будущем появятся дополнительные методы обрезки, использующие другое определение пространства, поэтому уточнение необходимо. String :: trim использует определение пробела в качестве любой кодовой точки, которая меньше или равна кодовой точке пробела (\ u0020.) Более новые методы обрезки будут использовать определение (пробела) в качестве любой кодовой точки, которая возвращает true при передаче в Предикат Character :: isWhitespace.

Метод isWhitespace(char) был добавлен в Character с помощью JDK 1.1, но метод isWhitespace(int) не был представлен в классе Character до JDK 1.5. Последний метод (принимающий параметр типа int) был добавлен для поддержки дополнительных символов. Комментарии Javadoc для класса Character определяют дополнительные символы (обычно моделируемые с помощью "кодовой точки" на основе int) по сравнению с символами BMP (обычно моделируемые одним символом):

Набор символов от U + 0000 до U + FFFF иногда называют базовой многоязычной плоскостью (BMP). Символы, кодовые точки которых больше, чем U + FFFF, называются дополнительными символами. Платформа Java использует представление UTF-16 в массивах символов и в классах String и StringBuffer. В этом представлении дополнительные символы представлены в виде пары значений символов... Следовательно, значение символа представляет кодовые точки базовой многоязычной плоскости (BMP), включая суррогатные кодовые точки или кодовые единицы кодирования UTF-16. Значение int представляет все кодовые точки Unicode, включая дополнительные кодовые точки.... Методы, которые принимают только значение символа, не могут поддерживать дополнительные символы.... Методы, принимающие значение типа int, поддерживают все символы Unicode, включая дополнительные символы.

OpenJDK Changeset.


Сравнение результатов сравнения между trim() и strip() - почему String.strip() в 5 раз быстрее, чем String.trim() для пустой строки в Java 11

Ответ 2

Вот unit тест, который иллюстрирует ответ @MikhailKholodkov, используя Java 11.

(Обратите внимание, что \u2000 выше \u0020 и не считается пробелом в 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());
    }
}