1. Обзор
В этом уроке мы познакомимся с различными вариантами создания строки
из N повторяющихся символов . Это удобно, когда нам нужно добавить отступы, создать ASCII-графику и т. д.
Эта проблема легко решается в JDK11, но если мы используем более раннюю версию, то доступно множество других решений. Мы начнем с наиболее распространенных и добавим другие подходы из некоторых библиотек.
2. Пример
Давайте определим константы, которые мы будем использовать во всех решениях для проверки сгенерированной строки:
private static final String EXPECTED_STRING = "aaaaaaa";
private static final int N = 7;
Итак, константа EXPECTED_STRING
представляет собой строку, которую нам нужно сгенерировать в решениях. Константа N
используется для определения количества повторений символов.
Теперь давайте рассмотрим варианты генерации строки из N повторяющихся символов a
.
3. Функция JDK11 String.repeat
В Java есть функция повтора
для создания копий исходной строки:
String newString = "a".repeat(N);
assertEquals(EXPECTED_STRING, newString);
Это позволяет нам повторять отдельные символы или многосимвольные строки:
String newString = "-->".repeat(5);
assertEquals("-->-->-->-->-->", newString);
Алгоритм, стоящий за этим, использует циклы для достаточно эффективного заполнения массивов символов.
Если у нас нет JDK11, то нам придется создавать алгоритм самостоятельно или использовать его из сторонней библиотеки. Лучшие из этих ИС вряд ли будут намного быстрее или проще в использовании, чем собственное решение JDK11.
4. Распространенные способы построения строки
4.1. StringBuilder
с циклом for
Начнем с класса StringBuilder
. Мы будем повторять цикл for
N раз, добавляя повторяющийся символ:
StringBuilder builder = new StringBuilder(N);
for (int i = 0; i < N; i++) {
builder.append("a");
}
String newString = builder.toString();
assertEquals(EXPECTED_STRING, newString);
При таком подходе мы получаем нужную строку. Вероятно, это самый простой для понимания метод , но он не обязательно самый быстрый во время выполнения .
4.2. char
Массив с циклом for
Мы можем заполнить массив символов
фиксированного размера желаемым символом и преобразовать его в строку:
char[] charArray = new char[N];
for (int i = 0; i < N; i++) {
charArray[i] = 'a';
}
String newString = new String(charArray);
assertEquals(EXPECTED_STRING, newString);
Это должно быть быстрее, поскольку не требует структуры с динамическим размером для хранения нашей строки по мере ее создания , а Java может эффективно преобразовывать массив символов в
строку.
4.3. Метод заполнения массивов
Вместо использования цикла мы можем использовать библиотечную функцию для заполнения нашего массива:
char charToAppend = 'a';
char[] charArray = new char[N];
Arrays.fill(charArray, charToAppend);
String newString = new String(charArray);
assertEquals(EXPECTED_STRING, newString);
Это короче и так же эффективно во время выполнения, как и предыдущее решение.
5. Генерация строки с помощью метода повтора
5.1. Метод повторения
Apache
Это решение требует добавления новой зависимости для библиотеки Apache Commons :
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
После добавления этой зависимости мы можем использовать метод repeat
из класса StringUtils
. Он принимает в качестве параметров символ для повторения и количество повторений символа :
char charToAppend = 'a';
String newString = StringUtils.repeat(charToAppend, N);
assertEquals(EXPECTED_STRING, newString);
5.2. Метод повторения
гуавы
Как и в предыдущем подходе, для этого требуется новая зависимость для библиотеки Guava :
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
Помимо того факта, что оно взято из другой библиотеки, это решение идентично решению Apache Commons:
String charToAppend = "a";
String newString = Strings.repeat(charToAppend, N);
assertEquals(EXPECTED_STRING, newString);
6. Генерация строки с помощью метода nCopies
Если мы представим нашу целевую строку как набор повторяющихся подстрок, то мы могли бы использовать утилиту List
для создания списка, а затем преобразовать полученный список в нашу окончательную строку String
. Для этого мы можем использовать метод nCopies
из класса Collections в пакете
java.util
:
public static <T> List<T> nCopies(int n, T o);
Хотя построение списка подстрок менее эффективно, чем наши решения, использующие фиксированный массив символов, может быть полезно повторить шаблон символов, а не только один символ.
6.1. Соединение
строк
и методы nCopies
Давайте создадим список односимвольных строк с помощью метода nCopies
и воспользуемся String.join
для преобразования его в наш результат:
String charToAppend = "a";
String newString = String.join("", Collections.nCopies(N, charToAppend));
assertEquals(EXPECTED_STRING, newString);
Методу String.join
нужен разделитель, для которого мы используем пустую строку.
6.2. Guava Joiner
и метод nCopies
Guava предлагает альтернативный соединитель строк, который мы также можем использовать:
String charToAppend = "a";
String newString = Joiner.on("").join(Collections.nCopies(N, charToAppend));
assertEquals(EXPECTED_STRING, newString);
7. Генерация строки
с помощью метода Stream generate
Недостатком создания списка подстрок является то, что мы создаем потенциально большой объект временного списка до того, как создадим окончательную строку.
Однако, начиная с Java 8, мы можем использовать метод generate
из Stream
API . В сочетании с методом limit
(для определения длины) и методом collect
мы можем сгенерировать строку из N повторяющихся символов :
String charToAppend = "a";
String newString = generate(() -> charToAppend)
.limit(length)
.collect(Collectors.joining());
assertEquals(exampleString, newString);
8. Генерация строки
с помощью Apache RandomStringUtils
Класс RandomStringUtils
из библиотеки Apache Commons
позволяет генерировать строку из N повторяющихся символов с использованием случайного
метода . Мы должны определить символ и количество повторений:
String charToAppend = "a";
String newString = RandomStringUtils.random(N, charToAppend);
assertEquals(EXPECTED_STRING, newString);
9. Заключение
В этой статье мы видели различные решения для генерации строки из N повторяющихся символов. Самый простой из них — String.repeat
, доступный начиная с JDK 11.
Для более ранних версий Java существует множество других возможных доступных опций. Лучший выбор будет зависеть от наших требований с точки зрения эффективности времени выполнения, простоты кодирования и доступности библиотек.
Как всегда, код этих примеров доступен на GitHub .