创建一个包含 n 个字符的字符串

在 Java 中有没有一种方法来创建一个具有指定数目的指定字符的字符串?在我的例子中,我需要创建一个包含10个空格的字符串。我现在的代码是:

final StringBuffer outputBuffer = new StringBuffer(length);
for (int i = 0; i < length; i++){
outputBuffer.append(" ");
}
return outputBuffer.toString();

还有更好的方法来完成同样的事情吗?特别是,我希望某些东西是快速的(在执行方面)。

254324 次浏览

For 循环将由编译器进行优化。在像您这样的情况下,您不需要关心自己的优化。相信编译器。

顺便说一句,如果有一种方法可以创建一个具有 n 个空格字符的字符串,那么它的编码方式与您刚才所做的相同。

我不知道什么内置的方法可以满足你的要求。然而,对于一个小的固定长度,如10,您的方法应该足够快。

嗯,现在我想想,也许 Arrays.fill:

char[] charArray = new char[length];
Arrays.fill(charArray, ' ');
String str = new String(charArray);

当然,我假设 fill方法执行与您的代码相同的操作,因此它的执行效果可能与您的代码相同,但至少这样的代码行更少。

只要用 StringBuilder代替 StringBuffer 就可以了,很难做到这一点。

如果您的长度是一个很大的数字,那么您可以实现一些更有效的 (但更笨拙)自我附加,在每次迭代中复制长度:

 public static String dummyString(char c, int len) {
if( len < 1 ) return "";
StringBuilder sb = new StringBuilder(len).append(c);
int remnant = len - sb.length();
while(remnant  > 0) {
if( remnant  >= sb.length() ) sb.append(sb);
else sb.append(sb.subSequence(0, remnant));
remnant  = len - sb.length();
}
return sb.toString();
}

此外,您可以尝试 Arrays.fill()方法(沮丧的表单设计师的答案)。

你可以用 StringBuilder代替 StringBuffer(后者不同步,在单线程应用程序中可能更快)

您可以创建 StringBuilder实例一次,而不是每次需要时都创建它。

就像这样:

class BuildString {
private final StringBuilder builder = new StringBuilder();
public String stringOf( char c , int times ) {


for( int i = 0 ; i < times ; i++  ) {
builder.append( c );
}
String result = builder.toString();
builder.delete( 0 , builder.length() -1 );
return result;
}


}

像这样使用它:

 BuildString createA = new BuildString();
String empty = createA.stringOf( ' ', 10 );

如果你把你的 createA作为一个实例变量,你可以节省创建实例的时间。

这不是线程安全的,如果你有多个线程,每个线程应该有自己的副本。

在大多数情况下,您只需要一定长度的 String,比如100个空格。您可以准备一个 String 数组,其中的索引号等于填充空格的字符串的大小,如果所需的长度在限制之内,则查找字符串; 如果在边界之外,则根据需要创建字符串。

这个怎么样?

char[] bytes = new char[length];
Arrays.fill(bytes, ' ');
String str = new String(bytes);

可能是使用 String API 的最短代码,仅限于:

String space10 = new String(new char[10]).replace('\0', ' ');


System.out.println("[" + space10 + "]");
// prints "[          ]"

作为一种方法,不需要直接实例化 char:

import java.nio.CharBuffer;


/**
* Creates a string of spaces that is 'spaces' spaces long.
*
* @param spaces The number of spaces to add to the string.
*/
public String spaces( int spaces ) {
return CharBuffer.allocate( spaces ).toString().replace( '\0', ' ' );
}

使用:

System.out.printf( "[%s]%n", spaces( 10 ) );

这个怎么样?

public String fillSpaces(int len) {
/* the spaces string should contain spaces exceeding the max needed */
String spaces = "                                                   ";
return spaces.substring(0,len);
}

编辑: 我已经写了一个简单的代码来测试这个概念,在这里我发现。

方法1: 在循环中添加单个空格:

  public String execLoopSingleSpace(int len){
StringBuilder sb = new StringBuilder();


for(int i=0; i < len; i++) {
sb.append(' ');
}


return sb.toString();
}

方法2: 附加100个空格和循环,然后是子字符串:

  public String execLoopHundredSpaces(int len){
StringBuilder sb = new StringBuilder("          ")
.append("          ").append("          ").append("          ")
.append("          ").append("          ").append("          ")
.append("          ").append("          ").append("          ");


for (int i=0; i < len/100 ; i++) {
sb.append("          ")
.append("          ").append("          ").append("          ")
.append("          ").append("          ").append("          ")
.append("          ").append("          ").append("          ");
}


return sb.toString().substring(0,len);
}

结果我创建了12,345,678个空间:

C:\docs\Projects> java FillSpace 12345678
method 1: append single spaces for 12345678 times. Time taken is **234ms**. Length of String is 12345678
method 2: append 100 spaces for 123456 times. Time taken is **141ms**. Length of String is 12345678
Process java exited with code 0

以及1000万个空位:

C:\docs\Projects> java FillSpace 10000000
method 1: append single spaces for 10000000 times. Time taken is **157ms**. Length of String is 10000000
method 2: append 100 spaces for 100000 times. Time taken is **109ms**. Length of String is 10000000
Process java exited with code 0

直接分配和迭代相结合总是花费更少的时间,平均60毫秒,当创建巨大的空间。对于较小的尺寸,这两个结果都可以忽略不计。

但请继续评论: -)

如果你只想要空格,那么这样如何:

String spaces = (n==0)?"":String.format("%"+n+"s", "");

这将导致 abs (n)空间;

也可以使用下面这样的简单方法

public static String padString(String str, int leng,char chr) {
for (int i = str.length(); i <= leng; i++)
str += chr;
return str;
}

我认为代码越少越好,它使用了 Guava Joiner 类:

Joiner . on (“”) . join (收藏品,复印件(10,“”)) ;

为了获得良好的性能,将来自 阿兹尼拉米尔沮丧的表单设计师的答案结合起来

private static final String BLANKS = "                       ";
private static String getBlankLine( int length )
{
if( length <= BLANKS.length() )
{
return BLANKS.substring( 0, length );
}
else
{
char[] array = new char[ length ];
Arrays.fill( array, ' ' );
return new String( array );
}
}

根据您的要求调整 BLANKS的大小。我特定的 BLANKS字符串大约是200个字符长度。

我强烈建议不要手写这个循环。 在您的编程生涯中,您将一次又一次地这样做。 人们阅读你的代码-包括你-总是不得不投入时间,即使只是几秒钟,消化循环的意义。

取而代之的是 重复使用,它是一个可用的库,提供了类似于 Apache Commons Lang中的 StringUtils.repeat的代码:

StringUtils.repeat(' ', length);

这样你也不必担心性能,因此所有血淋淋的细节 StringBuilder,编译器优化等隐藏。 如果函数执行得很慢,那么它就是库的错误。

使用 爪哇11会变得更加容易:

" ".repeat(length);

有一个这样的方法。这会在给定的 String的末尾附加所需的空格,使得给定的 String与特定长度的长度成正比。

public static String fillSpaces (String str) {


// the spaces string should contain spaces exceeding the max needed
String spaces = "                                                   ";
return str + spaces.substring(str.length());
}

我的贡献基于快速求幂的算法。

/**
* Repeats the given {@link String} n times.
*
* @param str
*            the {@link String} to repeat.
* @param n
*            the repetition count.
* @throws IllegalArgumentException
*             when the given repetition count is smaller than zero.
* @return the given {@link String} repeated n times.
*/
public static String repeat(String str, int n) {
if (n < 0)
throw new IllegalArgumentException(
"the given repetition count is smaller than zero!");
else if (n == 0)
return "";
else if (n == 1)
return str;
else if (n % 2 == 0) {
String s = repeat(str, n / 2);
return s.concat(s);
} else
return str.concat(repeat(str, n - 1));
}

我用另外两种方法测试了这个算法:

  • 使用 String.concat()连接字符串的常规 for 循环
  • 使用 StringBuilder的常规 for 循环

测试代码(对于较大的 n,使用 for 循环和 String.concat()进行串联会变慢,所以我在第5次迭代后将其省略)。

/**
* Test the string concatenation operation.
*
* @param args
*/
public static void main(String[] args) {
long startTime;
String str = " ";


int n = 1;
for (int j = 0; j < 9; ++j) {
n *= 10;
System.out.format("Performing test with n=%d\n", n);


startTime = System.currentTimeMillis();
StringUtil.repeat(str, n);
System.out
.format("\tStringUtil.repeat() concatenation performed in    %d milliseconds\n",
System.currentTimeMillis() - startTime);


if (j <5) {
startTime = System.currentTimeMillis();
String string = "";
for (int i = 0; i < n; ++i)
string = string.concat(str);
System.out
.format("\tString.concat() concatenation performed in        %d milliseconds\n",
System.currentTimeMillis() - startTime);
} else
System.out
.format("\tString.concat() concatenation performed in        x milliseconds\n");
startTime = System.currentTimeMillis();
StringBuilder b = new StringBuilder();
for (int i = 0; i < n; ++i)
b.append(str);
b.toString();
System.out
.format("\tStringBuilder.append() concatenation performed in %d milliseconds\n",
System.currentTimeMillis() - startTime);
}
}

结果:

Performing test with n=10
StringUtil.repeat() concatenation performed in    0 milliseconds
String.concat() concatenation performed in        0 milliseconds
StringBuilder.append() concatenation performed in 0 milliseconds
Performing test with n=100
StringUtil.repeat() concatenation performed in    0 milliseconds
String.concat() concatenation performed in        1 milliseconds
StringBuilder.append() concatenation performed in 0 milliseconds
Performing test with n=1000
StringUtil.repeat() concatenation performed in    0 milliseconds
String.concat() concatenation performed in        1 milliseconds
StringBuilder.append() concatenation performed in 1 milliseconds
Performing test with n=10000
StringUtil.repeat() concatenation performed in    0 milliseconds
String.concat() concatenation performed in        43 milliseconds
StringBuilder.append() concatenation performed in 5 milliseconds
Performing test with n=100000
StringUtil.repeat() concatenation performed in    0 milliseconds
String.concat() concatenation performed in        1579 milliseconds
StringBuilder.append() concatenation performed in 1 milliseconds
Performing test with n=1000000
StringUtil.repeat() concatenation performed in    0 milliseconds
String.concat() concatenation performed in        x milliseconds
StringBuilder.append() concatenation performed in 10 milliseconds
Performing test with n=10000000
StringUtil.repeat() concatenation performed in    7 milliseconds
String.concat() concatenation performed in        x milliseconds
StringBuilder.append() concatenation performed in 112 milliseconds
Performing test with n=100000000
StringUtil.repeat() concatenation performed in    80 milliseconds
String.concat() concatenation performed in        x milliseconds
StringBuilder.append() concatenation performed in 1107 milliseconds
Performing test with n=1000000000
StringUtil.repeat() concatenation performed in    1372 milliseconds
String.concat() concatenation performed in        x milliseconds
StringBuilder.append() concatenation performed in 12125 milliseconds

结论:

  • 对于大型 n-使用递归方法
  • 对于小的 n-For 循环具有足够的速度

RRandom StringUtils 有一个条款,用于根据给定的输入大小创建字符串。 不能评论的速度,但它是一个一行。

RandomStringUtils.random(5,"\t");

创建一个输出

不要

如果您不希望在代码中看到 < em > 0 ,那么最好使用。

在 Java8中,你可以使用 String.join:

String.join("", Collections.nCopies(n, s));

可以使用标准的 String.format函数生成 N 个空格。 例如:

String.format("%5c", ' ');

生成一个带有5个空格的字符串。

或者

int count = 15;
String fifteenSpacebars = String.format("%" + count + "c", ' ');

形成一个由15个空格键组成的字符串。

如果要重复另一个符号,则必须用所需的符号替换空格:

int count = 7;
char mySymbol = '#';
System.out.println(String.format("%" + count + "c", ' ').replaceAll("\\ ", "\\" + mySymbol));

产出:

#######

考虑到我们有:

String c = "c"; // character to repeat, for empty it would be " ";
int n = 4; // number of times to repeat
String EMPTY_STRING = ""; // empty string (can be put in utility class)

Java8(使用数据流)

String resultOne = IntStream.range(0,n)
.mapToObj(i->c).collect(Collectors.joining(EMPTY_STRING)); // cccc

Java8(使用 nCopies)

String resultTwo = String.join(EMPTY_STRING, Collections.nCopies(n, c)); //cccc

使用 StringUtils: 重复(’,10)

由于 Java11,您可以简单地使用 String.repeat(count)来解决您的问题。

返回一个字符串,其值是此字符串重复 count次的串联。

如果该字符串为空或者 count为零,则返回空字符串。

所以代码不是循环,而是这样:

" ".repeat(length);

爪哇11以来:

" ".repeat(10);

爪哇8以来:

generate(() -> " ").limit(10).collect(joining());

地点:

import static java.util.stream.Collectors.joining;
import static java.util.stream.Stream.generate;

使用番石榴的最短解决方案:

Strings.repeat(" ", len)

通过 在 java 中重复 String 的简单方法

希望字符串的大小是固定的,所以你要么垫或截断,为制表数据..。

class Playground {
private static String fixStrSize(String s, int n) {
return String.format("%-" + n + "s", String.format("%." + n +"s", s));
}


public static void main(String[ ] args) {
System.out.println("|"+fixStrSize("Hell",8)+"|");
System.out.println("|"+fixStrSize("Hells Bells Java Smells",8)+"|");
}
}

|Hell    |
|Hells Be|

优秀的参考 给你

在 Java8中,我不需要使用任何外部库就可以实现这一点

String sampleText = "test"
int n = 3;
String output = String.join("", Collections.nCopies(n, sampleText));
System.out.println(output);

输出是

testtesttest

Int c = 10; 字符串空间 = String.format (“%”+ c + “ c”,’) ; 这能解决你的问题。