Перейти к основному содержимому

Подсчет пробелов в строке Java

· 5 мин. чтения

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 .