【问题标题】:What is the easiest way to generate a String of n repeated characters?生成包含 n 个重复字符的字符串的最简单方法是什么?
【发布时间】:2011-10-29 18:07:03
【问题描述】:

给定一个字符 c 和一个数字 n,我如何创建一个包含 n 个 c 重复的字符串?手动操作太麻烦了:

StringBuilder sb = new StringBuilder(n);
for (int i = 0; i < n; ++i)
{
    sb.append(c);
}
String result = sb.toString();

肯定有一些静态库函数已经为我做了这个?

【问题讨论】:

标签: java string character


【解决方案1】:

只需将其添加到您自己的...

public static String generateRepeatingString(char c, Integer n) {
    StringBuilder b = new StringBuilder();
    for (Integer x = 0; x < n; x++)
        b.append(c);
    return b.toString();
}

Or Apache commons 有一个可以添加的实用程序类。

【讨论】:

  • 你为什么用Integer而不是int
  • 个人喜好。没关系。
  • @Mike - 没关系?用你自己的话“这非常浪费。for 循环的每次迭代都会”调用intValue(3 次)和valueOf(一次/交互)最终创建一个新的整数(x > 127)!
【解决方案2】:
int n = 10;
char[] chars = new char[n];
Arrays.fill(chars, 'c');
String result = new String(chars);

编辑:

自提交此答案已有 9 年了,但它仍然不时引起一些关注。与此同时,Java 8 引入了函数式编程特性。给定一个字符c 和所需的重复次数count,下面的单行代码可以和上面一样。

String result = IntStream.range(1, count).mapToObj(index -> "" + c).collect(Collectors.joining());

但请注意,它比数组方法慢。除了最苛刻的情况外,它几乎不重要。除非它是在每秒执行数千次的代码中,否则不会有太大的不同。这也可以与 String 而不是 char 一起使用以重复多次,因此更加灵活。无需第三方库。

【讨论】:

  • 它是单引号,不是变量。除非我在这里遗漏了什么……我今天有点昏昏沉沉。
  • 我说的是原始问题中的 c,而不是你的答案
  • @Tedil: "给定一个 字符 c 和一个数字 n [...]"
  • 啊,对。由于自动拆箱,也应该适用于Character 对象。我假设它是charCharacter
  • Stream 方法确实不是优势。但是从 Java 11 开始,你可以使用(""+c).repeat(n)
【解决方案3】:

如果可以,请使用来自 Apache Commons 的 StringUtils Lang

StringUtils.repeat("ab", 3);  //"ababab"

【讨论】:

  • 有用的知道:commons-lang3 有一个采用char 而不是String 的方法。最近版本中的实现实际上与我的答案相同(使用Arrays.fill)。采用 String 的版本有一堆用于优化的分支代码路径。如果输入字符串的长度为 1,它最终会调用采用 char 的方法。 commons-lang3 之前的版本似乎也表现良好。如果你的类路径中碰巧有 commons-lang,你也可以使用它。
【解决方案4】:

【讨论】:

    【解决方案5】:

    这是一个 O(logN) 方法,基于标准的二进制幂算法:

    public static String repChar(char c, int reps) {
        String adder = Character.toString(c);
        String result = "";
        while (reps > 0) {
            if (reps % 2 == 1) {
                result += adder;
            }
            adder += adder;
            reps /= 2;
        }        
        return result;
    }
    

    reps 的负值返回空字符串。

    【讨论】:

    • 假设 += for String 需要 O(1) 时间,这需要 O(log N) 时间。我不认为你的假设是合理的。
    • @Tsuyoshi Ito:好点。使用预先确定大小的 StringBuilder 会更接近理想。
    • @TsuyoshiIto 您根据您定义的单位操作使用 O()。在这种情况下,+= 是单位运算,因此 O(log N) 是有效的。但是您说得对,在内部,+= 将使用 StringBuilder,这可能会产生开销。
    • 似乎这涉及在每个连续的 += 上复制越来越长的字符串。所以这个算法在每个 += 上比前一个做更多的工作。它还会产生垃圾。所以使用'+='作为'单位'真的不是一个很好的看待它的方式。您可能最好使用单个 StringBuilder 和循环来逐个添加字符。将涉及更少的垃圾和字符串复制,这可能意味着整体性能更好。
    • 在 O(log N) 中没有办法做到这一点。如果你想要一串n 重复字符,这意味着n 内存位置必须用一个值填充。这充其量是 O(N)。您的算法是变相的循环中的字符串连接。使用 StringBuilder 最终最多仍会归结为线性时间。
    【解决方案6】:

    看看这个样本

    Integer  n=10;
    String s="a";
    String repeated = new String(new char[n]).replace("\0", s);
    

    Simple way to repeat a String in java 的形式回答,所以在那里投票

    【讨论】:

      【解决方案7】:

      为了了解速度损失,我测试了两个版本,一个使用 Array.fill,一个使用 StringBuilder。

      public static String repeat(char what, int howmany) {
          char[] chars = new char[howmany];
          Arrays.fill(chars, what);
          return new String(chars);
      }
      

      public static String repeatSB(char what, int howmany) {
          StringBuilder out = new StringBuilder(howmany);
          for (int i = 0; i < howmany; i++)
              out.append(what);
          return out.toString();
      }
      

      使用

      public static void main(String... args) {
          String res;
          long time;
      
          for (int j = 0; j < 1000; j++) {
              res = repeat(' ', 100000);
              res = repeatSB(' ', 100000);
          }
          time = System.nanoTime();
          res = repeat(' ', 100000);
          time = System.nanoTime() - time;
          System.out.println("elapsed repeat: " + time);
      
          time = System.nanoTime();
          res = repeatSB(' ', 100000);
          time = System.nanoTime() - time;
          System.out.println("elapsed repeatSB: " + time);
      }
      

      (注意 main 函数中的循环是为了启动 JIT)

      结果如下:

      elapsed repeat  : 65899
      elapsed repeatSB: 305171
      

      这是一个巨大的差异

      【讨论】:

      • 您的测试方法有缺陷。使用 JMH 获得准确的结果。
      • 确实这不是一个完美的基准(完美的基准根本不存在)购买它清楚地显示了一种方法与另一种方法相比有多慢。
      • 差别不大。当然,相对而言,第二种方法的速度几乎慢了 5 倍。但是我们正在研究大约需要 65 _micro_seconds 的东西和需要 305 _micro_seconds 的东西之间的区别。它甚至不是毫秒级的。那是为了制作一个 100000 字符的字符串。我永远不会基于这种微观优化而不是 Java 中的易读性做出选择。仅当它涉及每秒将执行多次的代码时例外。
      【解决方案8】:

      我正在添加另一种解决方法:

      public String buildString(Character character, int nTimes) {
          return String.format("%" + nTimes + "s", " ").replace(' ', character);
      }
      

      【讨论】:

        【解决方案9】:

        Java SE 11

        String#repeat​(int count),作为 Java SE 11 的一部分引入,使其非常容易实现。

        演示:

        public class Main {
            public static void main(String[] args) {
                char ch = 'c';
                int n = 20;
                String result = String.valueOf(ch).repeat(n);
                System.out.println(result);
            }
        }
        

        输出:

        cccccccccccccccccccc
        

        【讨论】:

          【解决方案10】:

          如果您不在 Java 11+ 上(否则我会选择 Arvind Kumar Avinash's answer),您还可以结合使用 String#join(CharSequence, Iterable&lt;? extends CharSequence&gt;Collections#nCopies(int, T)

          String result = String.join("", Collections.nCopies(c, n));
          

          【讨论】:

            猜你喜欢
            • 2013-11-12
            • 1970-01-01
            • 2021-08-21
            • 1970-01-01
            • 2013-02-12
            • 2021-03-16
            • 1970-01-01
            • 2010-11-17
            • 1970-01-01
            相关资源
            最近更新 更多