概述
在这个教程中,我们将探讨生成包含N个重复字符的字符串的不同方法。当需要添加填充空格、创建ASCII艺术等时,这些技巧非常有用。
在JDK11及以上版本中,这个问题很容易解决,但对于早期版本,还有许多其他解决方案可供选择。我们将从最常见的开始,并介绍一些库中提供的其他方法。
2. 示例
让我们定义所有解决方案中将使用的常量:
private static final String EXPECTED_STRING = "aaaaaaa";
private static final int N = 7;
其中,EXPECTED_STRING
常量表示我们需要生成的字符串,而N
常量用于定义字符重复次数。
现在,我们来看看如何生成重复字符a
的N个字符字符串。
3. JDK11 String.repeat
函数
Java提供了repeat
函数来构建源字符串的副本:
String newString = "a".repeat(N);
assertEquals(EXPECTED_STRING, newString);
这使得我们可以重复单个字符或多字符字符串:
String newString = "-->".repeat(5);
assertEquals("-->-->-->-->-->", newString);
这个功能背后的算法使用循环高效地填充字符数组。
如果我们没有JDK11,就需要自己编写算法,或者使用第三方库的解决方案。但这些通常不会比JDK11原生的解决方案更快或更易于使用。
4. 构建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);
这种方法更短,与前一个解决方案一样在运行时效率高。
5. 使用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);
6. 使用nCopies
方法生成字符串
如果我们将目标字符串视为重复子字符串的集合,那么我们可以使用List
工具来构造列表,然后将结果转换为最终的String
。为此,我们可以使用java.util
包中的Collections
类中的nCopies
方法:
public static <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);
7. 使用Stream.generate
方法生成字符串
创建子字符串列表的缺点是我们会在构造最终字符串之前创建一个可能很大的临时列表对象。
然而,从Java 8开始,我们可以使用Stream
API的generate
方法。结合limit
方法(定义长度)和collect
方法,我们可以生成包含N个重复字符的字符串:
String charToAppend = "a";
String newString = generate(() -> charToAppend)
.limit(length)
.collect(Collectors.joining());
assertEquals(exampleString, newString);
8. 使用Apache的RandomStringUtils
生成字符串
Apache Commons库中的RandomStringUtils
类提供了使用random
方法生成包含N个重复字符的字符串的功能。我们需要定义一个字符和重复次数:
String charToAppend = "a";
String newString = RandomStringUtils.random(N, charToAppend);
assertEquals(EXPECTED_STRING, newString);
9. 结论
在这篇文章中,我们了解了生成包含N个重复字符字符串的各种方法。其中最简单的是JDK 11及以后版本的String.repeat
。
对于早期的Java版本,还有许多其他可能的选择。最好的选择将取决于我们的需求,包括运行时效率、编码简洁性和可用库。如往常一样,这些示例的代码可以在GitHub上找到。