1. Overview
1.概述
In this tutorial, we’ll get familiar with different options for generating a String of N repeated characters. This comes in handy when we need to add padding whitespace, produce ASCII art, etc.
在本教程中,我们将熟悉用于生成N个重复字符的字符串的不同选项。当我们需要添加填充空白、产生ASCII艺术等时,这就很方便了。
This problem is easily solved in JDK11, but if we’re using an earlier version, then there are many other solutions available. We’ll start with the most common ones and add other approaches from some libraries.
这个问题在JDK11中很容易解决,但如果我们使用的是更早的版本,那么就有很多其他的解决方案了。我们将从最常见的开始,并添加一些库中的其他方法。
2. Example
2.例子
Let’s define the constants we’ll use in all solutions to validate a generated string:
让我们来定义我们将在所有解决方案中使用的常量,以验证生成的字符串。
private static final String EXPECTED_STRING = "aaaaaaa";
private static final int N = 7;
So, the EXPECTED_STRING constant represents the string we need to generate in solutions. The N constant is used to define the number of character repetitions.
所以,EXPECTED_STRING常数代表我们需要在解决方案中生成的字符串。N 常数用于定义字符重复的数量。
Now, let’s inspect the options for generating a string of N repeated characters a.
现在,让我们检查一下生成N个重复字符a的字符串的选项。
3. The JDK11 String.repeat Function
3.JDK11的String.repeat函数
Java has a repeat function to build copies of a source string:
Java有一个repeat函数来建立一个源字符串的副本。
String newString = "a".repeat(N);
assertEquals(EXPECTED_STRING, newString);
This allows us to repeat single characters, or multi-character strings:
这使我们能够重复单个字符,或多字符的字符串。
String newString = "-->".repeat(5);
assertEquals("-->-->-->-->-->", newString);
The algorithm behind this uses loops to fill arrays of characters quite efficiently.
这背后的算法使用循环来填充字符数组,相当有效。
If we don’t have JDK11, then we will have to create an algorithm ourselves, or use one from a third party library. The best of these IS unlikely to be much faster or easier to use than the JDK11 native solution.
如果我们没有JDK11,那么我们将不得不自己创建一个算法,或者使用第三方库的算法。其中最好的算法不可能比JDK11的本地解决方案快得多,也不可能更容易使用。
4. Common Ways to Build a String
4.构建字符串的常见方法
4.1. StringBuilder With a for Loop
4.1.StringBuilder与for循环
Let’s start with the StringBuilder class. We’ll iterate through a for loop N times appending the repeated character:
让我们从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);
With this approach, we get the desired string. This is probably the easiest method to understand, but it’s not necessarily the fastest at runtime.
通过这种方法,我们得到了想要的字符串。这可能是最容易理解的方法,但它在运行时不一定最快。
4.2. char Array With a for Loop
4.2.char数组与for循环
We can fill a fixed size char array with our desired character and convert that to a string:
我们可以用我们想要的字符填充一个固定大小的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);
This ought to be faster, as it does not require a dynamically sized structure to store our string as we build it, and Java can efficiently convert a char array to String.
这应该会更快,因为它不需要一个动态大小的结构来存储我们的字符串,因为我们建立它,而且Java可以有效地将char数组转换为String.。
4.3. Arrays fill Method
4.3.Arrays fill方法
Rather than use a loop, we can use a library function to fill our array:
我们可以使用一个库函数来填充我们的数组,而不是使用一个循环。
char charToAppend = 'a';
char[] charArray = new char[N];
Arrays.fill(charArray, charToAppend);
String newString = new String(charArray);
assertEquals(EXPECTED_STRING, newString);
This is shorter and is as efficient at runtime as the previous solution.
这更短,并且在运行时与之前的解决方案一样高效。。
5. Generating the String With the repeat Method
5.用repeat方法生成字符串
5.1. The Apache repeat Method
5.1.Apache的repeat方法
This solution requires adding a new dependency for the Apache Commons library:
这个解决方案需要为Apache Commons库添加一个新的依赖项。
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
After adding this dependency, we can use the repeat method from the StringUtils class. It takes as the parameters a character for repeating and a number of times the character should be repeated:
加入这个依赖关系后,我们可以使用repeat类中的StringUtils方法。它的参数是一个用于重复的字符和该字符应该被重复的次数。
char charToAppend = 'a';
String newString = StringUtils.repeat(charToAppend, N);
assertEquals(EXPECTED_STRING, newString);
5.2. The Guava repeat Method
5.2.Guava的repeat方法
Like the previous approach, this one requires a new dependency for the Guava library:
和前面的方法一样,这个方法需要对Guava库有一个新的依赖。
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
Other than the fact that it comes from a different library, this solution is identical to the Apache Commons one:
除了来自一个不同的库之外,这个解决方案与Apache Commons的解决方案是相同的。
String charToAppend = "a";
String newString = Strings.repeat(charToAppend, N);
assertEquals(EXPECTED_STRING, newString);
6. Generating the String With the nCopies Method
6.用nCopies方法生成字符串
If we think of our target string as a collection of repeated substrings, then we could use a List utility to construct the list and then convert the resulting list into our final String. For this, we can use the nCopies method from the Collections class in the java.util package:
如果我们将目标字符串视为重复子字符串的集合,那么我们可以使用List工具来构建列表,然后将生成的列表转换为我们最终的String。为此,我们可以使用java.util包中Collections类中的nCopies方法。
public static <T> List<T> nCopies(int n, T o);
While constructing a list of substrings is less effective than our solutions that use a fixed array of characters, it can be helpful to repeat a pattern of characters rather than just a single character.
虽然构建子串列表的效果不如我们使用固定的字符数组的解决方案,但重复一个字符模式而不仅仅是一个字符,可能会有帮助。
6.1. String join and the nCopies Methods
6.1.String join和nCopies方法
Let’s create a list of single-character strings with the nCopies method and use String.join to convert it to our result:
让我们用nCopies方法创建一个单字符字符串的列表,并使用String.join将其转换为我们的结果。
String charToAppend = "a";
String newString = String.join("", Collections.nCopies(N, charToAppend));
assertEquals(EXPECTED_STRING, newString);
The String.join method needs a delimiter, for which we’re using the empty string.
String.join方法需要一个分隔符,为此我们使用空字符串。
6.2. Guava Joiner and the nCopies Method
6.2.Guava Joiner和nCopies方法
Guava offers an alternative string joiner, which we can also use:
Guava提供了一个替代的字符串连接器,我们也可以使用它。
String charToAppend = "a";
String newString = Joiner.on("").join(Collections.nCopies(N, charToAppend));
assertEquals(EXPECTED_STRING, newString);
7. Generating the String With the Stream generate Method
7.用Stream generate方法生成字符串
The disadvantage of creating a list of substrings is that we’re creating a potentially large temporary list object before we construct our final string.
创建子字符串列表的缺点是,在我们构建最终的字符串之前,我们要创建一个潜在的大型临时列表对象。
However, since Java 8, we can use the generate method from the Stream API. In combination with the limit method (for defining the length) and the collect method, we can generate a string of N repeated characters:
然而,从Java 8开始,我们可以使用Stream API中的generate方法。结合limit方法(用于定义长度)和collect方法,我们可以生成N个重复字符的字符串。
String charToAppend = "a";
String newString = generate(() -> charToAppend)
.limit(length)
.collect(Collectors.joining());
assertEquals(exampleString, newString);
8. Generating the String With Apache’s RandomStringUtils
8.用Apache的RandomStringUtils生成String
The RandomStringUtils class from the Apache Commons library enables generating a string of N repeated characters using the random method. We have to define a character and the number of repetitions:
来自Apache Commons库的RandomStringUtils类能够使用random方法生成N个重复字符的字符串。我们必须定义一个字符和重复的数量。
String charToAppend = "a";
String newString = RandomStringUtils.random(N, charToAppend);
assertEquals(EXPECTED_STRING, newString);
9. Conclusion
9.结语
In this article, we saw various solutions for generating a string of N repeated characters. The easiest of these is String.repeat, available from JDK 11 onwards.
在这篇文章中,我们看到了生成N个重复字符的字符串的各种解决方案。其中最简单的是String.repeat,从JDK 11开始可用。
For earlier versions of Java there are many other possible available options. The best choice will depend on our requirements in terms of runtime efficiency, ease of coding, and availability of libraries.
对于早期的Java版本,还有许多其他可能的可用选项。最好的选择将取决于我们在运行时效率、编码的简易性和库的可用性方面的要求。
As always, the code for these examples is available over on GitHub.
像往常一样,这些例子的代码可以在GitHub上找到over。