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

C. *_*oss 125 java string stringbuffer

java中是否有一种方法可以创建具有指定数量的指定字符的字符串?在我的例子中,我需要创建一个包含10个空格的字符串.我目前的代码是:

StringBuffer outputBuffer = new StringBuffer(length);
for (int i = 0; i < length; i++){
   outputBuffer.append(" ");
}
return outputBuffer.toString();
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来完成同样的事情.特别是我想要一些快速的(在执行方面).

pol*_*nts 158

可能是使用StringAPI 的最短代码,仅限:

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

System.out.println("[" + space10 + "]");
// prints "[          ]"
Run Code Online (Sandbox Code Playgroud)

作为一种方法,无需直接实例化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', ' ' );
}
Run Code Online (Sandbox Code Playgroud)

调用使用:

System.out.printf( "[%s]%n", spaces( 10 ) );
Run Code Online (Sandbox Code Playgroud)

  • 即使我喜欢单线程,我认为FrustratedWithFormsDes的解决方案在执行时更好,因为它避免了检查每个\ 0并简单地分配空间. (4认同)

Fru*_*ner 63

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

char[] charArray = new char[length];
Arrays.fill(charArray, ' ');
String str = new String(charArray);
Run Code Online (Sandbox Code Playgroud)

当然,我假设该fill方法与您的代码完全相同,因此它可能会执行相同的操作,但至少这是更少的行.

  • 在检查了源代码之后,事实上这确实与OP发布的内容完全相同:http://www.docjar.com/html/api/java/util/Arrays.java.html的第806行 (2认同)
  • @Lord Torgamus是否编辑了OP的问题?因为在我看到的版本中,他在StringBuffer.append()上循环,并且Frustrated的版本正在进行填充(当然循环执行对数组的char赋值).根本不是一回事. (2认同)
  • @Lord Torgamus - 同意这一点。可惜 jvm 不能只做一个 memset。我们为宽字符支付的价格。 (2认同)
  • @Pops值得注意的是,如果在整个代码_and_(标准和外部)库代码中一致地使用Arrays.fill()函数来完成此工作,那么它很适合用于Hotspot编译,并且机会更大被发现您的CPU缓存。将来的JVM可能会将其分配为_intrinsic_函数。滚动自己会切断所有这些性能优势... (2认同)

mfu*_*chs 58

我强烈建议不要手工编写循环.你将在编程生涯中一遍又一遍地做这件事.阅读你的代码的人 - 包括你 - 总是需要花时间,即使只是几秒钟,消化循环的意义.

而是重用一个可用的库,提供StringUtils.repeatApache Commons Lang类似的代码:

StringUtils.repeat(' ', length);
Run Code Online (Sandbox Code Playgroud)

这样你也不必担心性能问题,因此StringBuilder隐藏了编译器优化等所有血腥细节.如果函数变得很慢,那么这将是库的错误.

使用Java 11,它变得更加容易:

" ".repeat(length);
Run Code Online (Sandbox Code Playgroud)

  • 另一方面,如果项目中尚未使用StringUtils,那么为这样一个简单的任务添加另一个依赖项可能会过度. (4认同)

kal*_*kin 35

for循环将由编译器优化.在像你这样的情况下,你不需要自己关心优化.相信编译器.:)

编辑:顺便说一句,如果有一种方法可以创建一个包含n个空格字符的字符串,那么它的编码方式与您刚刚编写的方式相同.


epo*_*pox 29

Java 11 开始

" ".repeat(10);
Run Code Online (Sandbox Code Playgroud)

Java 8 开始

generate(() -> " ").limit(10).collect(joining());
Run Code Online (Sandbox Code Playgroud)

在哪里:

import static java.util.stream.Collectors.joining;
import static java.util.stream.Stream.generate;
Run Code Online (Sandbox Code Playgroud)

  • @JGFMK 我觉得 `"=".repeat(10)` 与这里的 `"=" * 10` 足够接近。它更明确/更不容易出错(例如,Python 中的“=” * 10` 是“==========”,但在 Java 中是“610”),而且长度也不是那么长。 (4认同)

Vit*_*nko 22

在Java 8中,您可以使用String.join:

String.join("", Collections.nCopies(n, s));
Run Code Online (Sandbox Code Playgroud)


Bry*_*ada 12

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

String spaces = (n==0)?"":String.format("%"+n+"s", "");
Run Code Online (Sandbox Code Playgroud)

这会产生abs(n)空间;

  • 那速度怎么样?我的印象格式比较慢.它必须解析字符串才能创建它. (6认同)

mei*_*chh 8

我认为这是可能的代码越少,它使用的是Guava Joiner类:

Joiner .on("").join(Collections.nCopies(10,""));

  • @nasch Guava 不是问题的一部分。但无论如何,在 2018 年,当您可以使用 Java 8 中添加的 String.join() 时,确实没有理由使用 Guava 的 Joiner。请参阅 /sf/answers/3010835761/ (2认同)

Nie*_*len 5

我的贡献基于快速取幂算法.

/**
 * 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));
}
Run Code Online (Sandbox Code Playgroud)

我针对另外两种方法测试了算法:

  • 定期循环String.concat()用于连接字符串
  • 定期循环使用a StringBuilder

测试代码(使用for循环进行连接String.concat(),对于较大的进行缓慢n,所以我在第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);
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:

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
Run Code Online (Sandbox Code Playgroud)

结论:

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

  • 这是一个有趣的实现.不幸的是,与你的结论相反,对于大n来说效率非常低.我怀疑这是因为每次连接字符串时都会发生很多内存分配.尝试将其编写为包含StringBuilder而不是String的递归方法的包装器.我打赌你会发现结果会好得多. (4认同)
  • 在对这样的事情进行微观基准测试时,您需要采取许多预防措施,而且我认为您不会采取任何预防措施!围绕这段代码的主要性能问题可能很容易就是Hotspot编译,它创造了多少垃圾等等.我敢打赌所有那些`if`语句都会搞砸CPU的分支预测.这应该使用JMH(http://openjdk.java.net/projects/code-tools/jmh/)重做,否则它有点无意义. (3认同)

小智 5

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

String.format("%5c", ' ');
Run Code Online (Sandbox Code Playgroud)

用5个空格组成一个字符串。

要么

int count = 15;
String fifteenSpacebars = String.format("%" + count + "c", ' ');
Run Code Online (Sandbox Code Playgroud)

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

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

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

输出:

#######
Run Code Online (Sandbox Code Playgroud)


Sam*_*ipp 5

从Java 11开始,您可以简单地使用它String.repeat(count)来解决您的问题。

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

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

因此,除了循环,您的代码将如下所示:

" ".repeat(length);
Run Code Online (Sandbox Code Playgroud)