我正在寻找一个简单的公共方法或操作符,允许我重复一些字符串n次。我知道我可以使用for循环来写这个,但我希望在必要时避免for循环,并且应该在某个地方存在一个简单的直接方法。

String str = "abc";
String repeated = str.repeat(3);

repeated.equals("abcabcabc");

相关:

重复字符串javascript 通过重复给定次数的另一个字符串创建NSString

编辑

当它们不是完全必要的时候,我尽量避免使用for循环,因为:

They add to the number of lines of code even if they are tucked away in another function. Someone reading my code has to figure out what I am doing in that for loop. Even if it is commented and has meaningful variables names, they still have to make sure it is not doing anything "clever". Programmers love to put clever things in for loops, even if I write it to "only do what it is intended to do", that does not preclude someone coming along and adding some additional clever "fix". They are very often easy to get wrong. For loops involving indexes tend to generate off by one bugs. For loops often reuse the same variables, increasing the chance of really hard to find scoping bugs. For loops increase the number of places a bug hunter has to look.


当前回答

如果你像我一样想使用谷歌Guava而不是Apache Commons。你可以在Guava Strings类中使用repeat方法。

Strings.repeat("-", 60);

其他回答

Java 8的字符串。join结合Collections.nCopies提供了一种简洁的方法:

// say hello 100 times
System.out.println(String.join("", Collections.nCopies(100, "hello")));

使用递归,你可以做以下事情(使用三元运算符,最多一行):

public static final String repeat(String string, long number) {
    return number == 1 ? string : (number % 2 == 0 ? repeat(string + string, number / 2) : string + repeat(string + string, (number - 1) / 2));
}

我知道,它很丑,而且可能效率不高,但它就是一行!

所以你想避免循环?

现在你知道了:

public static String repeat(String s, int times) {
    if (times <= 0) return "";
    else return s + repeat(s, times-1);
}

(当然我知道这是丑陋和低效的,但它没有循环:-p)

你想要更简单更漂亮吗?使用jython:

s * 3

编辑:让我们优化一下:-D

public static String repeat(String s, int times) {
   if (times <= 0) return "";
   else if (times % 2 == 0) return repeat(s+s, times/2);
   else return s + repeat(s+s, times/2);
}

Edit2:我已经为4个主要的替代方案做了一个快速而粗略的基准测试,但我没有时间多次运行它来获得几个输入的平均值和绘制时间……如果有人想试试,下面是代码:

public class Repeat {
    public static void main(String[] args)  {
        int n = Integer.parseInt(args[0]);
        String s = args[1];
        int l = s.length();
        long start, end;

        start = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            if(repeatLog2(s,i).length()!=i*l) throw new RuntimeException();
        }
        end = System.currentTimeMillis();
        System.out.println("RecLog2Concat: " + (end-start) + "ms");

        start = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            if(repeatR(s,i).length()!=i*l) throw new RuntimeException();
        }               
        end = System.currentTimeMillis();
        System.out.println("RecLinConcat: " + (end-start) + "ms");

        start = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            if(repeatIc(s,i).length()!=i*l) throw new RuntimeException();
        }
        end = System.currentTimeMillis();
        System.out.println("IterConcat: " + (end-start) + "ms");

        start = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            if(repeatSb(s,i).length()!=i*l) throw new RuntimeException();
        }
        end = System.currentTimeMillis();
        System.out.println("IterStrB: " + (end-start) + "ms");
    }

    public static String repeatLog2(String s, int times) {
        if (times <= 0) {
            return "";
        }
        else if (times % 2 == 0) {
            return repeatLog2(s+s, times/2);
        }
        else {
           return s + repeatLog2(s+s, times/2);
        }
    }

    public static String repeatR(String s, int times) {
        if (times <= 0) {
            return "";
        }
        else {
            return s + repeatR(s, times-1);
        }
    }

    public static String repeatIc(String s, int times) {
        String tmp = "";
        for (int i = 0; i < times; i++) {
            tmp += s;
        }
        return tmp;
    }

    public static String repeatSb(String s, int n) {
        final StringBuilder sb = new StringBuilder();
        for(int i = 0; i < n; i++) {
            sb.append(s);
        }
        return sb.toString();
    }
}

它有两个参数,第一个是迭代的次数(每个函数运行的重复次数参数从1..n),第二个是要重复的字符串。

到目前为止,快速检查不同输入的运行时间,得出的排名大致如下(从好到坏):

迭代StringBuilder追加(1x)。 递归连接log2调用(~3x)。 递归级联线性调用(~30x)。 迭代级联线性(~45x)。

我从来没有想到递归函数比for循环快:-o

玩得开心。

字符串:重复

". ".repeat(7)  // Seven period-with-space pairs: . . . . . . . 

Java 11中的新方法是String::repeat,它完全符合你的要求:

String str = "abc";
String repeated = str.repeat(3);
repeated.equals("abcabcabc");

它的Javadoc说:

/**
 * Returns a string whose value is the concatenation of this
 * string repeated {@code count} times.
 * <p>
 * If this string is empty or count is zero then the empty
 * string is returned.
 *
 * @param count number of times to repeat
 *
 * @return A string composed of this string repeated
 * {@code count} times or the empty string if this
 * string is empty or count is zero
 *
 * @throws IllegalArgumentException if the {@code count} is
 * negative.
 *
 * @since 11
 */ 

简单的循环

public static String repeat(String string, int times) {
    StringBuilder out = new StringBuilder();
    while (times-- > 0) {
        out.append(string);
    }
    return out.toString();
}