1. Обзор
Метод String.trim() удаляет конечные и начальные пробелы. Но нет никакой поддержки для простого выполнения LTrim или RTrim.
В этом уроке мы рассмотрим несколько способов, которыми мы можем это реализовать; в конце концов, мы сравним их производительность.
2. цикл while
Самое простое решение-пройти через строку, используя пару циклов while |/.
Для L-Trim мы будем читать строку слева направо, пока не столкнемся с символом без пробелов:
int i = 0;
while (i < s.length() && Character.isWhitespace(s.charAt(i))) {
i++;
}
String ltrim = s.substring(i);
ltrim – это подстрока, начинающаяся с первого символа, не содержащего пробелов.
Или для RTrim, мы будем читать вашу строку справа налево, пока не столкнемся с символом без пробелов:
int i = s.length()-1;
while (i >= 0 && Character.isWhitespace(s.charAt(i))) {
i--;
}
String rtrim = s.substring(0,i+1);rtrim -это подстрока, начинающаяся в начале и заканчивающаяся на первом символе без пробелов.
3. String.replaceAll С Использованием Регулярных Выражений
Другой вариант-использовать String.replaceAll() и регулярное выражение:
String ltrim = src.replaceAll("^\\s+", "");
String rtrim = src.replaceAll("\\s+$", "");(\\s+) – это регулярное выражение, которое соответствует одному или нескольким пробелам. Символы ( ^ ) и ($) в начале и в конце регулярного выражения соответствуют началу и концу строки.
4. Pattern.compile() и .matches()
Мы также можем повторно использовать регулярные выражения с java.util.regex.Pattern :
private static Pattern LTRIM = Pattern.compile("^\\s+");
private static Pattern RTRIM = Pattern.compile("\\s+$");
String ltrim = LTRIM.matcher(s).replaceAll("");
String rtim = RTRIM.matcher(s).replaceAll("");5. Apache Commons
Кроме того, мы можем воспользоваться методами Apache Commons StringUtils#stripStart и #stripped для удаления пробелов.
Для этого давайте сначала добавим | commons-lang3 зависимость :
org.apache.commons commons-lang3 3.11
Следуя документации, мы используем null для удаления пробелов:
String ltrim = StringUtils.stripStart(src, null); String rtrim = StringUtils.stripEnd(src, null);
6. Гуава
Наконец, мы воспользуемся методами Guava CharMatcher#trimLeadingFrom и #trimTrailingFrom , чтобы получить тот же результат.
Опять же, давайте добавим соответствующую зависимость Maven, на этот раз ее guava :
com.google.guava guava 28.2-jre
И в Гуаве это очень похоже на то, как это делается в Apache Commons, только с более целенаправленными методами:
String ltrim = CharMatcher.whitespace().trimLeadingFrom(s); String rtrim = CharMatcher.whitespace().trimTrailingFrom(s);
7. Сравнение производительности
Давайте посмотрим на эффективность методов. Как обычно, мы будем использовать фреймворк с открытым исходным кодом Java Microbenchmark Harness (JMH) для сравнения различных альтернатив в наносекундах.
7.1. Настройка бенчмарка
Для начальной настройки бенчмарка мы использовали пять вилок и среднее время расчета времени в наносекундах:
@Fork(5) @State(Scope.Benchmark) @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS)
В методе установки мы инициализируем исходное поле сообщения и полученную строку для сравнения с:
@Setup
public void setup() {
src = " White spaces left and right ";
ltrimResult = "White spaces left and right ";
rtrimResult = " White spaces left and right";
}Все тесты сначала удаляют левый пробел, затем удаляют правый пробел и, наконец, сравнивают результаты с ожидаемыми строками.
7.2. цикл while
Для нашего первого теста давайте используем подход while loop:
@Benchmark
public boolean whileCharacters() {
String ltrim = whileLtrim(src);
String rtrim = whileRtrim(src);
return checkStrings(ltrim, rtrim);
}7.3. String.replaceAll() с регулярным выражением
Тогда давайте попробуем String.replaceAll() :
@Benchmark
public boolean replaceAllRegularExpression() {
String ltrim = src.replaceAll("^\\s+", "");
String rtrim = src.replaceAll("\\s+$", "");
return checkStrings(ltrim, rtrim);
}7.4. Pattern.compile().matches()
После этого следует Pattern.compile().matches() :
@Benchmark
public boolean patternMatchesLTtrimRTrim() {
String ltrim = patternLtrim(src);
String rtrim = patternRtrim(src);
return checkStrings(ltrim, rtrim);
}7.5. Apache Commons
В-четвертых, Apache Commons:
@Benchmark
public boolean apacheCommonsStringUtils() {
String ltrim = StringUtils.stripStart(src, " ");
String rtrim = StringUtils.stripEnd(src, " ");
return checkStrings(ltrim, rtrim);
}7.6. Гуава
И, наконец, давайте использовать гуаву:
@Benchmark
public boolean guavaCharMatcher() {
String ltrim = CharMatcher.whitespace().trimLeadingFrom(src);
String rtrim = CharMatcher.whitespace().trimTrailingFrom(src);
return checkStrings(ltrim, rtrim);
}7.7. Анализ результатов
И мы должны получить некоторые результаты, подобные следующим:
# Run complete. Total time: 00:16:57 Benchmark Mode Cnt Score Error Units LTrimRTrim.apacheCommonsStringUtils avgt 100 108,718 ± 4,503 ns/op LTrimRTrim.guavaCharMatcher avgt 100 113,601 ± 5,563 ns/op LTrimRTrim.patternMatchesLTtrimRTrim avgt 100 850,085 ± 17,578 ns/op LTrimRTrim.replaceAllRegularExpression avgt 100 1046,660 ± 7,151 ns/op LTrimRTrim.whileCharacters avgt 100 110,379 ± 1,032 ns/op
И похоже, что наши победители-это while loop, Apache Commons и Guava!
8. Заключение
В этом уроке мы рассмотрели несколько различных способов удаления пробелов в начале и в конце строки /.
Для получения этого результата мы использовали while loop, String.replaceAll (), /Pattern.matcher().replaceAll(), Apache Commons и Guava.
Как всегда, код доступен на GitHub .