代码之家  ›  专栏  ›  技术社区  ›  C. Ross trotttrotttrott

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

  •  113
  • C. Ross trotttrotttrott  · 技术社区  · 15 年前

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

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

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

    21 回复  |  直到 6 年前
        1
  •  34
  •   kalkin    15 年前

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

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

        2
  •  146
  •   Dave Jarvis James Eichele    10 年前

    可能是使用 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 ) );
    
        3
  •  54
  •   Boann    10 年前

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

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

    当然,我认为 fill 方法与代码执行相同的操作,因此它可能执行相同的操作,但至少行数更少。

        4
  •  52
  •   mfuchs krzaq    6 年前

    我强烈建议不要手工编写循环。 在您的编程生涯中,您将一次又一次地这样做。 阅读你的代码的人——包括你在内——总是需要花费时间来消化循环的意义,即使只是几秒钟。

    相反 重新使用 提供类似代码的可用库之一 StringUtils.repeat Apache Commons Lang :

    StringUtils.repeat(' ', length);
    

    这样你也不必为性能操心,因此所有的血淋淋的细节 StringBuilder 隐藏编译器优化等。 如果函数的速度变慢了,那将是库中的一个bug。

    Java 11 它变得更容易:

    " ".repeat(length);
    
        5
  •  21
  •   Vitalii Fedorenko    8 年前

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

    String.join("", Collections.nCopies(n, s));
    
        6
  •  11
  •   BryceCicada    12 年前

    如果您只想要空格,那么如何处理:

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

    会产生abs(n)空间;

        7
  •  8
  •   nathanfranke    7 年前

    我认为这是可能的代码更少,它使用了guava joiner类:

    Joiner on(“”)加入 Collections.nCopies (10,“”);

        8
  •  5
  •   Niels Billen    10 年前

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

    /**
     * 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));
    }
    

    我用其他两种方法测试了算法:

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

    测试代码(使用for循环和 字符串() 变慢为大 n ,所以我在第五次迭代之后就把它省略了)。

    /**
     * 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循环有足够的速度
        9
  •  3
  •   Martijn Courteaux    15 年前

    这个怎么样?

    char[] bytes = new char[length];
    Arrays.fill(bytes, ' ');
    String str = new String(bytes);
    
        10
  •  2
  •   Whimsical    9 年前

    RandomStringUtils 具有从给定输入大小创建字符串的设置。 不能评论速度,但它是一行。

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

    创建输出

    t \ t t t

    如果你不想看最好 0 在您的代码中。

        11
  •  1
  •   Andreas Dolk    15 年前

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

        12
  •  1
  •   Alexey Gusev    6 年前

    您可以使用标准 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));
    

    输出:

    #######
    
        13
  •  1
  •   akhil_mittal    6 年前

    考虑到我们有:

    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)
    

    Java 8(使用流)

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

    Java 8(使用N副本)

    String resultTwo = String.join(EMPTY_STRING, Collections.nCopies(n, c)); //cccc
    
        14
  •  0
  •   leonbloy    15 年前

    只需将StringBuffer替换为 StringBuilder . 很难克服。

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

     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() 指责( 对窗体设计人员感到失望 的答案。

        15
  •  0
  •   OscarRyz    15 年前

    你可以代替 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 作为实例变量,您可以节省创建实例的时间。

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

        16
  •  0
  •   Community CDub    8 年前

    为了获得良好的表现,请结合以下答案: aznilamir FrustratedWithFormsDesigner

    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 取决于您的要求。我的专一 坯料 字符串的长度约为200个字符。

        17
  •  0
  •   msrd0 Gordon Linoff    10 年前

    有这样的方法。在给定的 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());
    }
    
        18
  •  0
  •   Icegras    6 年前

    使用stringutils: stringutils.repeat(“”,10)

        19
  •  -1
  •   Yashpal Singla    12 年前

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

    public static String padString(String str, int leng,char chr) {
            for (int i = str.length(); i <= leng; i++)
                str += chr;
            return str;
        }
    
        20
  •  -2
  •   aznilamir    13 年前

    这个怎么样?

    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);
      }
    

    我得到的结果是创建12345678个空格:

    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
    

    对于10000000个空间:

    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毫秒。对于较小的尺寸,两种结果都可以忽略不计。

    但请继续评论:—)

        21
  •  -3
  •   Pops Atula    15 年前

    我不知道有什么内置方法可以满足你的要求。但是,对于像10这样的小固定长度,您的方法应该足够快。