生成 N 个重复字符的 Java 字符串
1. 概述
在本教程中,我们将熟悉生成 N 个重复字符的字符串的不同选项。当我们需要添加填充空白、生成 ASCII art 等时,这会派上用场。
这个问题在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 有一个repeat函数来构建源字符串的副本:
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.具有 for 循环的 char 数组
我们可以用我们想要的字符填充固定大小的 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 数组转换为 字符串。
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 个重复字符的字符串的各种解决方案。其中最简单的是 String.repeat,从 JDK 11 开始提供。
对于早期版本的 Java,还有许多其他可能的可用选项。最佳选择将取决于我们在运行时效率、编码简易性和库可用性方面的要求。
与往常一样,这些示例的代码可以在GitHub上找到。