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

107

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

  • repeat(int)- Повторяет строку столько раз, сколько указано в intпараметре
  • lines() - Использует Spliterator для ленивого предоставления строк из исходной строки
  • isBlank() - Указывает, пуста ли строка или содержит только символы пробела
  • stripLeading() - Удаляет пустое пространство с самого начала
  • 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?

Михаил Холодков
источник

Ответы:

106

Вкратце: strip()это "Unicode-совместимая" эволюция trim().

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.) Новые методы обрезки будут использовать определение (белого) пробела как любую кодовую точку, которая возвращает истину при передаче в Предикат Character :: isWhitespace.

Этот метод isWhitespace(char)был добавлен в CharacterJDK 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. В этом представлении дополнительные символы представлены как пара значений char ... Таким образом, значение char представляет кодовые точки базовой многоязычной плоскости (BMP), включая суррогатные кодовые точки или кодовые единицы кодировки UTF-16. Значение int представляет все кодовые точки Unicode, включая дополнительные кодовые точки. ... Методы, которые принимают только значение char, не могут поддерживать дополнительные символы. ... Методы, которые принимают значение int, поддерживают все символы Unicode, включая дополнительные символы.

OpenJDK набор изменений .


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

Михаил Холодков
источник
7
Интересно, что символ '\ u0000' не удаляется полосой, а удаляется обрезкой.
CHEM_Eugene
32

Вот модульный тест, который иллюстрирует ответ @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());
    }
}
Майкл Истер
источник
0

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

trim () удаляет все начальные и конечные символы , значение ASCII которых меньше или равно 32 ('U + 0020' или пробел).

Согласно стандартам Unicode существуют различные символы пробела, имеющие значение ASCII более 32 ('U + 0020'). Пример: 8193 (U + 2001).

Чтобы идентифицировать эти пробелы, новый метод isWhitespace (int) был добавлен из Java 1.5 в класс Character. Этот метод использует юникод для идентификации пробелов. Вы можете узнать больше о пробелах Unicode здесь .

Новая полоса метода, добавленная в java 11, использует этот метод Character.isWhitespace (int), чтобы охватить широкий диапазон символов пробела и удалить их.

пример

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

Вывод

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

Примечание. Если вы работаете на компьютере с Windows, возможно, вы не сможете увидеть аналогичный результат из-за ограниченного набора Unicode. вы можете попробовать некоторые онлайн-компиляторы для тестирования этого кода.

ссылка: разница между методом обрезки и полосы java

Рупеш Агравал
источник