【问题标题】:Java - Create a new String instance with specified length and filled with specific character. Best solution? [duplicate]Java - 创建一个具有指定长度并填充特定字符的新字符串实例。最佳解决方案? [复制]
【发布时间】:2010-12-20 15:34:34
【问题描述】:

我确实检查了其他问题;这个问题的重点是以最有效的方式解决这个特定问题。

有时您想创建一个具有指定长度的新字符串,并使用默认字符填充整个字符串。

也就是说,如果你可以使用new String(10, '*') 并从那里创建一个新字符串,长度为 10 个字符,所有字符都带有 *,那就太棒了。

因为这样的构造函数不存在,并且您不能从 String 扩展,您必须创建一个包装类或一个方法来为您执行此操作。

此时我正在使用这个:

protected String getStringWithLengthAndFilledWithCharacter(int length, char charToFill) {
    char[] array = new char[length];
    int pos = 0;
    while (pos < length) {
        array[pos] = charToFill;
        pos++;
    }
    return new String(array);
}

它仍然缺少任何检查(即,当长度为 0 时它不起作用)。我首先构造数组,因为我相信它比使用字符串连接或使用 StringBuffer 更快。

其他人有更好的解决方案吗?

【问题讨论】:

    标签: java string


    【解决方案1】:

    Apache Commons Lang(可能在任何重要项目的类路径中都足够有用)有StringUtils.repeat()

    String filled = StringUtils.repeat("*", 10);
    

    简单!

    【讨论】:

    • 这应该是票数最高的答案。谢谢;)
    • 这是最好的答案。当前的最佳答案以一种不直观的方式使用 leftpad 来做一些它并不真正打算做的事情,这使得理解应该发生的事情变得更加困难。这个答案自我记录更好。
    • @Benjamin 我同意并将其标记为“真实”答案:)
    【解决方案2】:

    在 Java 11 中,您有 repeat:

    String s = " ";
    s = s.repeat(1);
    

    (虽然在撰写本文时still subject to change

    【讨论】:

    • 这应该是新的最佳答案。
    【解决方案3】:

    你可以像这样使用while循环:

    String text = "Hello";
    while (text.length() < 10) { text += "*"; }
    System.out.println(text);
    

    会给你:

    Hello*****
    

    或者使用自定义方法得到相同的结果:

        public static String extendString(String text, String symbol, Integer len) {
            while (text.length() < len) { text += symbol; }
            return text;
        }
    

    然后只需调用:

    extendString("Hello", "*", 10)
    

    设置长度检查以防止无限循环也是一个好主意。

    【讨论】:

      【解决方案4】:

      如果您知道最大长度,则可以使用单个预定义的字符串来提高性能,例如:

      字符串模板 = "####################################";

      然后在知道长度后简单地执行一个子字符串。

      【讨论】:

      • +1:我刚刚在另一篇文章中读到,子字符串创建了一个字符串,它只使用与原始字符串相同的 char[]。所以这是一个 O(1) 操作(无循环),它可以节省内存(如果这是一个真正的问题)
      【解决方案5】:

      使用Google Guava的解决方案

      String filled = Strings.repeat("*", 10);
      

      【讨论】:

        【解决方案6】:

        小米解决方案:

          pw = "1321";
            if (pw.length() < 16){
              for(int x = pw.length() ; x < 16 ; x++){
                pw  += "*";
              }
            }
        

        输出:

        1321************
        

        【讨论】:

          【解决方案7】:

          以上都很好。你介意我问你一个问题 - 这会给你带来问题吗?在你知道是否需要优化之前,我觉得你正在优化。

          现在是我的过度设计的解决方案。在许多(不是全部)情况下,您可以使用 CharSequence 代替字符串。

          public class OneCharSequence implements CharSequence {
            private final char value;
            private final int length;
            public OneCharSequence(final char value, final int length) {
              this.value = value;
              this.length = length;
            }
            public char   charAt(int index)  {
               if(index < length) return value;
               throw new IndexOutOfBoundsException();
            }
            public int length() {
              return length;
            }
            public CharSequence subSequence(int start, int end) {
               return new OneCharSequence(value, (end-start));
            }
            public String toString() {
              char[] array = new char[length];
              Arrays.fill(array, value);
              return new String(array);
            }
          }
          

          【讨论】:

            【解决方案8】:

            使用Google Guava 的解决方案,因为我更喜欢它而不是 Apache Commons-Lang:

            /**
             * Returns a String with exactly the given length composed entirely of
             * the given character.
             * @param length the length of the returned string
             * @param c the character to fill the String with
             */
            public static String stringOfLength(final int length, final char c)
            {
                return Strings.padEnd("", length, c);
            }
            

            【讨论】:

            • 查看 javacavaj 的答案,了解使用番石榴的更简洁的解决方案。
            【解决方案9】:

            一些可能的解决方案。

            这会创建一个长度乘以“0”填充的字符串,然后用 charToFill(老派)替换“0”。

            String s = String.format("%0" + length + "d", 0).replace('0', charToFill);
            

            这将使用 charToFill 创建一个包含长度乘以字符串的列表,然后将列表连接到一个字符串中。

            String s = String.join("", Collections.nCopies(length, String.valueOf(charToFill)));
            

            这将使用 charToFill 创建一个无限的带有字符串的 java8 流,将输出限制为长度并使用字符串连接器(新学校)收集结果。

            String s = Stream.generate(() -> String.valueOf(charToFill)).limit(length).collect(Collectors.joining());
            

            【讨论】:

              【解决方案10】:

              使用Dollar 很简单:

              String filled = $("=").repeat(10).toString(); // produces "=========="
              

              【讨论】:

              • 评论中有9个=
              【解决方案11】:

              试试这个求职者

              String stringy =null;
               byte[] buffer =  new byte[100000];
                          for (int i = 0; i < buffer.length; i++) {
                          buffer[i] =0;
              
                      }
                          stringy =StringUtils.toAsciiString(buffer);
              

              【讨论】:

                【解决方案12】:
                char[] chars = new char[10];
                Arrays.fill(chars, '*');
                String text = new String(chars);
                

                【讨论】:

                  【解决方案13】:

                  试试这个使用 substring(int start, int end);方法

                  String myLongString = "abcdefghij";
                  if (myLongString .length() >= 10)
                  String shortStr = myLongString.substring(0, 5)+ "...";
                  

                  这将返回 abcde。

                  【讨论】:

                    【解决方案14】:

                    额外说明:似乎所有创建新String 实例的公共方式都必然涉及到您正在使用的任何缓冲区的副本,无论是char[]StringBuffer 还是StringBuilder。来自String javadoc(并在其他类的相应toString方法中重复):

                    字符数组的内容被复制;随后的修改 字符数组不影响 新创建的字符串。

                    因此,在“快速填充”数组之后,您最终可能会进行大量内存复制操作。可以避免此问题的唯一解决方案是来自 @mlk 的解决方案,前提是您可以直接使用建议的 CharSequence 实现(可能是这种情况)。

                    PS:我会将此作为评论发布,但我还没有足够的声誉来这样做。

                    【讨论】:

                      【解决方案15】:

                      无需循环,只需使用标准 Java 库类:

                      protected String getStringWithLengthAndFilledWithCharacter(int length, char charToFill) {
                        if (length > 0) {
                          char[] array = new char[length];
                          Arrays.fill(array, charToFill);
                          return new String(array);
                        }
                        return "";
                      }
                      

                      如您所见,我还为length == 0 案例添加了合适的代码。

                      【讨论】:

                      • Arrays.fill() 中的代码不会包含循环...
                      • 也许可以,但是 1) 它可能会更快,并且 2) 那是您不需要编写的代码。
                      • 很好的发现。是的 Arrays.fill 本身做了一个 for 循环。但从根本上说,这更好。
                      • 如果 (length
                      • 很好的解决方案,因为它不会添加新的依赖项。 +1
                      【解决方案16】:
                      public static String fillString(int count,char c) {
                          StringBuilder sb = new StringBuilder( count );
                          for( int i=0; i<count; i++ ) {
                              sb.append( c ); 
                          }
                          return sb.toString();
                      }
                      

                      怎么了?

                      【讨论】:

                        【解决方案17】:

                        只需使用来自apache commons lang 项目的 StringUtils 类。你有一个leftPad 方法:

                        StringUtils.leftPad("foobar", 10, '*'); // Returns "****foobar"
                        

                        【讨论】:

                        • +1 - 这正是他想要的(又名“酷”)。对于完全相同的行为,但这很明显,请执行以下操作:StringUtils.leftPad("", 10, '*');
                        • +1 不错的解决方案,尽管我不会为此在我的项目中添加一个 jar。
                        • 谢谢。是的,这看起来是一种更合适的使用方式。幸运的是我已经在使用这个罐子了,所以我可以立即使用它。
                        • 或者使用repeat(),它不需要在开头使用空字符串,并且可以说意图更清晰(见我的回答)
                        • 这个 jar 超过 300kb??呸,不用谢。不适用于移动应用程序。不需要过时的软件。
                        猜你喜欢
                        • 1970-01-01
                        • 2012-12-29
                        • 2021-11-30
                        • 2012-11-14
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多