1. Обзор
Когда мы работаем со строками Java, иногда нам нужно подсчитать, сколько пробелов содержится в строке.
Существуют различные способы получения результата. В этом кратком руководстве мы увидим, как это сделать, на примерах.
2. Пример входной строки
Прежде всего, давайте подготовим входную строку в качестве примера:
String INPUT_STRING = " This string has nine spaces and a Tab:' '";
Строка выше содержит девять пробелов и символ табуляции, заключенный в одинарные кавычки. Наша цель состоит в том, чтобы считать символы пробела только в заданной входной строке .
Таким образом, наш ожидаемый результат:
int EXPECTED_COUNT = 9;
Далее давайте рассмотрим различные решения, чтобы получить правильный результат.
Сначала мы решим задачу с помощью стандартной библиотеки Java, а затем решим ее с помощью некоторых популярных внешних библиотек.
Наконец, в этом руководстве мы рассмотрим все решения в методах модульного тестирования.
3. Использование стандартной библиотеки Java
3.1. Классическое решение: зацикливание и подсчет
Это, пожалуй, самый простой способ решить проблему.
Проходим по всем символам входной строки. Кроме того, мы поддерживаем переменную счетчика и увеличиваем счетчик, когда видим пробел.
Наконец, мы получим количество пробелов в строке:
@Test
void givenString_whenCountSpaceByLooping_thenReturnsExpectedCount() {
int spaceCount = 0;
for (char c : INPUT_STRING.toCharArray()) {
if (c == ' ') {
spaceCount++;
}
}
assertThat(spaceCount).isEqualTo(EXPECTED_COUNT);
}
3.2. Использование потокового API Java 8
Stream API существует с Java 8.
Кроме того, начиная с Java 9, в класс String
был добавлен новый метод chars()
для преобразования значений char
из String
в экземпляр IntStream
.
Если мы работаем с Java 9 или более поздней версии, мы можем объединить две функции, чтобы решить проблему в одну строку:
@Test
void givenString_whenCountSpaceByJava8StreamFilter_thenReturnsExpectedCount() {
long spaceCount = INPUT_STRING.chars().filter(c -> c == (int) ' ').count();
assertThat(spaceCount).isEqualTo(EXPECTED_COUNT);
}
3.3. Использование метода Regex Matcher.find ()
До сих пор мы встречали решения, учитывающие поиск пробелов в заданной строке. Мы использовали символ == ' ',
чтобы проверить, является ли символ пробелом.
Регулярные выражения (Regex) — еще одно мощное оружие для поиска строк, а Java хорошо поддерживает Regex.
Следовательно, мы можем определить один пробел как шаблон и использовать метод Matcher.find()
, чтобы проверить, найден ли шаблон во входной строке.
Кроме того, чтобы получить количество пробелов, мы увеличиваем счетчик каждый раз, когда найден шаблон:
@Test
void givenString_whenCountSpaceByRegexMatcher_thenReturnsExpectedCount() {
Pattern pattern = Pattern.compile(" ");
Matcher matcher = pattern.matcher(INPUT_STRING);
int spaceCount = 0;
while (matcher.find()) {
spaceCount++;
}
assertThat(spaceCount).isEqualTo(EXPECTED_COUNT);
}
3.4. Использование метода String.replaceAll()
Использовать метод Matcher.find()
для поиска пробелов довольно просто. Однако, поскольку мы говорим о регулярном выражении, могут быть и другие быстрые способы подсчета пробелов.
Мы знаем, что можем выполнять «поиск и замену» с помощью метода String.replaceAll()
.
Поэтому, если мы заменим во входной строке все символы, не являющиеся пробелами, на пустую строку, результатом будут все пробелы из ввода .
Итак, если мы хотим получить количество, длина полученной строки будет ответом. Далее, давайте попробуем эту идею:
@Test
void givenString_whenCountSpaceByReplaceAll_thenReturnsExpectedCount() {
int spaceCount = INPUT_STRING.replaceAll("[^ ]", "").length();
assertThat(spaceCount).isEqualTo(EXPECTED_COUNT);
}
Как видно из приведенного выше кода, у нас есть только одна строка для подсчета.
Стоит отметить, что в вызове String.replaceAll()
мы использовали шаблон «[^ ]»
вместо «\\S».
Это потому, что мы хотели бы заменить символы без пробелов, а не только символы без пробелов.
3.5. Использование метода String.split()
Мы видели, что решение с методом String.replaceAll()
аккуратное и компактное. Теперь давайте рассмотрим еще одну идею решения проблемы: использование метода String.split()
.
Как мы знаем, мы можем передать шаблон методу String.split()
и получить массив строк, разделенных по шаблону.
Итак, идея в том, что мы можем разделить входную строку одним пробелом. Тогда количество пробелов в исходной строке будет на единицу меньше, чем длина массива строк .
Теперь давайте посмотрим, работает ли эта идея:
@Test
void givenString_whenCountSpaceBySplit_thenReturnsExpectedCount() {
int spaceCount = INPUT_STRING.split(" ").length - 1;
assertThat(spaceCount).isEqualTo(EXPECTED_COUNT);
}
4. Использование внешних библиотек
Библиотека Apache Commons Lang 3 широко используется в Java-проектах. Кроме того, Spring — популярный фреймворк среди энтузиастов Java.
Обе библиотеки предоставили удобный служебный класс строк.
Теперь давайте посмотрим, как подсчитывать пробелы во входной строке с помощью этих библиотек.
4.1. Использование библиотеки Apache Commons Lang 3
Библиотека Apache Commons Lang 3 предоставляет класс StringUtil
, который содержит множество удобных методов, связанных со строками.
Чтобы подсчитать пробелы в строке, мы можем использовать метод countMatches()
в этом классе.
Прежде чем мы начнем использовать класс StringUtil
, мы должны проверить, находится ли библиотека в пути к классам. Мы можем добавить зависимость с последней версией в наш pom.xml
:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
Теперь давайте создадим модульный тест, чтобы показать, как использовать этот метод:
@Test
void givenString_whenCountSpaceUsingApacheCommons_thenReturnsExpectedCount() {
int spaceCount = StringUtils.countMatches(INPUT_STRING, " ");
assertThat(spaceCount).isEqualTo(EXPECTED_COUNT);
}
4.2. Использование весны
Сегодня многие Java-проекты основаны на фреймворке Spring. Итак, если мы работаем со Spring, то хорошая строковая утилита, предоставляемая Spring, уже готова к использованию: StringUtils
.
Да, у него то же имя, что и у класса в Apache Commons Lang 3. Кроме того, он предоставляет метод countOccurrencesOf()
для подсчета появления символа в строке.
Это именно то, что мы ищем:
@Test
void givenString_whenCountSpaceUsingSpring_thenReturnsExpectedCount() {
int spaceCount = StringUtils.countOccurrencesOf(INPUT_STRING, " ");
assertThat(spaceCount).isEqualTo(EXPECTED_COUNT);
}
5. Вывод
В этой статье мы рассмотрели различные подходы к подсчету пробелов во входной строке.
Как всегда, код статьи можно найти на GitHub .