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


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

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

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

Строка.strip (), String.stripLeading () и String.стриптиз() методы обрезки белого пространства [как определено символом.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?

2 35

2 ответа:

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

КСО: JDK-8200378

Задача

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

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

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

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

Решение

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

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

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

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

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

OpenJDK Changeset.

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