生成包含N个重复字符的Java字符串
生成包含N个重复字符的Java字符串
在本教程中,我们将熟悉生成包含N个重复字符的字符串的不同选项。这在我们需要添加填充空白、生成ASCII艺术等时非常有用。
这个问题在JDK11中很容易解决,但如果我们使用的是早期版本,那么还有许多其他解决方案可用。我们将从最常见的方法开始,并添加一些来自第三方库的方法。
示例
让我们定义所有解决方案中将使用的常量,以验证生成的字符串:
private static final String EXPECTED_STRING = "aaaaaaa";
private static final int N = 7;
所以,EXPECTED_STRING 常量表示我们需要在解决方案中生成的字符串。N 常量用于定义字符重复的次数。
现在,让我们检查生成N个字符a的字符串的选项。
JDK11的String.repeat函数
Java有一个repeat函数来构建源字符串的副本:
String newString = "a".repeat(N);
assertEquals(EXPECTED_STRING, newString);
这允许我们重复单个字符或多字符字符串:
String newString = "-->".repeat(5);
assertEquals("-->-->-->-->-->", newString);
这个算法背后使用循环来非常高效地填充字符数组。
如果我们没有JDK11,那么我们必须自己创建一个算法,或者使用来自第三方库的算法。这些最好的解决方案不太可能比JDK11内置解决方案更快或更容易使用。
构建String的常见方法
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数组,并将其转换为字符串:
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可以高效地将char数组转换为String。
4.3 Arrays.fill方法
而不是使用循环,我们可以使用库函数来填充我们的数组:
char charToAppend = 'a';
char[] charArray = new char[N];
Arrays.fill(charArray, charToAppend);
String newString = new String(charArray);
assertEquals(EXPECTED_STRING, newString);
这更短,并且与之前的解决方案在运行时一样高效。
使用repeat方法生成字符串
5.1 Apache的repeat方法
这个解决方案需要为Apache Commons库添加一个新的依赖项:
`<dependency>``
``<groupId>``org.apache.commons``</groupId>``
``<artifactId>``commons-lang3``</artifactId>``
``<version>``3.13.0``</version>``
``</dependency>``
添加这个依赖项后,我们可以使用StringUtils类的repeat方法。它接受一个字符用于重复和字符应该重复的次数作为参数:
char charToAppend = 'a';
String newString = StringUtils.repeat(charToAppend, N);
assertEquals(EXPECTED_STRING, newString);
5.2 Guava的repeat方法
与前一种方法类似,这个解决方案需要为Guava库添加一个新的依赖项:
`<dependency>`
``<groupId>``com.google.guava``</groupId>``
``<artifactId>``guava``</artifactId>``
``<version>``32.1.3-jre``</version>``
``</dependency>``
除了它来自不同的库之外,这个解决方案与Apache Commons的解决方案是相同的:
String charToAppend = "a";
String newString = Strings.repeat(charToAppend, N);
assertEquals(EXPECTED_STRING, newString);
使用nCopies方法生成字符串
如果我们将目标字符串视为重复子字符串的集合,那么我们可以使用列表工具来构建列表,然后将结果列表转换为我们最终的String。为此,我们可以使用java.util包中的Collections类的nCopies方法:
public ``<T>`` List``<T>`` nCopies(int n, T o);
虽然使用固定字符数组的解决方案比我们使用子字符串列表的解决方案更有效,但构建字符模式的重复而不是单个字符的重复可能很有帮助。
6.1 String join和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);
使用Stream的generate方法生成字符串
创建子字符串列表的缺点是我们在构建最终字符串之前创建了一个潜在的大临时列表对象。
然而,自Java 8以来,我们可以使用Stream API的generate方法。结合limit方法(用于定义长度)和collect方法,我们可以生成N个重复字符的字符串:
String charToAppend = "a";
String newString = Stream.generate(() -> charToAppend)
.limit(N)
.collect(Collectors.joining());
assertEquals(EXPECTED_STRING, newString);
使用Apache的RandomStringUtils
Apache Commons库中的RandomStringUtils类使用random方法可以生成N个重复字符的字符串。我们必须定义一个字符和重复次数:
String charToAppend = "a";
String newString = RandomStringUtils.random(N, charToAppend);
assertEquals(EXPECTED_STRING, newString);
结论
在本文中,我们看到了生成N个重复字符字符串的各种解决方案。其中最简单的是String.repeat,从JDK 11开始可用。
对于Java的早期版本,还有许多其他可能的选项可用。最佳选择将取决于我们在运行时效率、编码便利性和库可用性方面的要求。
如往常一样,这些示例的代码可以在GitHub上找到。