在java中重复字符串的简单方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1235179/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Simple way to repeat a String in java
提问by Ethan Heilman
I'm looking for a simple commons method or operator that allows me to repeat some String ntimes. I know I could write this using a for loop, but I wish to avoid for loops whenever necessary and a simple direct method should exist somewhere.
我正在寻找一个简单的公共方法或运算符,它允许我重复一些字符串n次。我知道我可以使用 for 循环来编写它,但是我希望在必要时避免 for 循环,并且应该在某处存在一个简单的直接方法。
String str = "abc";
String repeated = str.repeat(3);
repeated.equals("abcabcabc");
Related to:
相关:
repeat string javascriptCreate NSString by repeating another string a given number of times
重复字符串 javascript通过将另一个字符串重复给定次数来创建 NSString
Edited
已编辑
I try to avoid for loops when they are not completely necessary because:
当它们不是完全必要时,我尽量避免使用 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.
即使它们隐藏在另一个函数中,它们也会增加代码行数。
阅读我的代码的人必须弄清楚我在那个 for 循环中做了什么。即使它被注释并具有有意义的变量名称,他们仍然必须确保它没有做任何“聪明”的事情。
程序员喜欢在 for 循环中放入聪明的东西,即使我写它是为了“只做它打算做的事情”,这并不妨碍有人加入并添加一些额外的聪明“修复”。
他们往往很容易出错。涉及索引的 for 循环往往会因一个错误而产生。
For 循环经常重用相同的变量,增加了很难找到范围错误的机会。
For 循环增加了 bug 猎人必须查看的位置数量。
采纳答案by Nicolai
String::repeat
String::repeat
". ".repeat( 7 ) // Seven period-with-space pairs: . . . . . . .
New in Java 11is the method String::repeat
that does exactly what you asked for:
Java 11中的新方法String::repeat
是完全按照您的要求执行的方法:
String str = "abc";
String repeated = str.repeat(3);
repeated.equals("abcabcabc");
Its Javadocsays:
它的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
*/
回答by ChssPly76
Commons Lang StringUtils.repeat()
Commons Lang StringUtils.repeat()
Usage:
用法:
String str = "abc";
String repeated = StringUtils.repeat(str, 3);
repeated.equals("abcabcabc");
回答by WolfmanDragon
If you are worried about performance, just use a StringBuilder inside the loop and do a .toString() on exit of the Loop. Heck, write your own Util Class and reuse it. 5 Lines of code max.
如果您担心性能,只需在循环内使用 StringBuilder 并在循环退出时执行 .toString() 。哎呀,编写您自己的 Util 类并重用它。最多 5 行代码
回答by Pyrolistical
This contains less characters than your question
这包含的字符比您的问题少
public static String repeat(String s, int n) {
if(s == null) {
return null;
}
final StringBuilder sb = new StringBuilder(s.length() * n);
for(int i = 0; i < n; i++) {
sb.append(s);
}
return sb.toString();
}
回答by dfa
using only JRE classes (System.arraycopy) and trying to minimizethe number of temp objects you can write something like:
仅使用 JRE 类(System.arraycopy)并尝试最小化临时对象的数量,您可以编写如下内容:
public static String repeat(String toRepeat, int times) {
if (toRepeat == null) {
toRepeat = "";
}
if (times < 0) {
times = 0;
}
final int length = toRepeat.length();
final int total = length * times;
final char[] src = toRepeat.toCharArray();
char[] dst = new char[total];
for (int i = 0; i < total; i += length) {
System.arraycopy(src, 0, dst, i, length);
}
return String.copyValueOf(dst);
}
EDIT
编辑
and without loops you can try with:
如果没有循环,您可以尝试:
public static String repeat2(String toRepeat, int times) {
if (toRepeat == null) {
toRepeat = "";
}
if (times < 0) {
times = 0;
}
String[] copies = new String[times];
Arrays.fill(copies, toRepeat);
return Arrays.toString(copies).
replace("[", "").
replace("]", "").
replaceAll(", ", "");
}
EDIT 2
编辑 2
using Collectionsis even shorter:
使用Collections甚至更短:
public static String repeat3(String toRepeat, int times) {
return Collections.nCopies(times, toRepeat).
toString().
replace("[", "").
replace("]", "").
replaceAll(", ", "");
}
however I still like the first version.
不过我还是喜欢第一个版本。
回答by Imagist
Despite your desire not to use loops, I think you should use a loop.
尽管您不想使用循环,但我认为您应该使用循环。
String repeatString(String s, int repetitions)
{
if(repetitions < 0) throw SomeException();
else if(s == null) return null;
StringBuilder stringBuilder = new StringBuilder(s.length() * repetitions);
for(int i = 0; i < repetitions; i++)
stringBuilder.append(s);
return stringBuilder.toString();
}
Your reasons for not using a for loop are not good ones. In response to your criticisms:
您不使用 for 循环的原因不是很好。回应您的批评:
- Whatever solution you use will almost certainly be longer than this. Using a pre-built function only tucks it under more covers.
- Someone reading your code will have to figure out what you're doing in that non-for-loop. Given that a for-loop is the idiomatic way to do this, it would be much easier to figure out if you did it with a for loop.
- Yes someone might add something clever, but by avoiding a for loop you aredoing something clever. That's like shooting yourself in the foot intentionally to avoid shooting yourself in the foot by accident.
- Off-by-one errors are also mind-numbingly easy to catch with a single test. Given that you should be testing your code, an off-by-one error should be easy to fix and catch. And it's worth noting: the code above does not contain an off-by-one error. For loops are equally easy to get right.
- So don't reuse variables. That's not the for-loop's fault.
- Again, so does whatever solution you use. And as I noted before; a bug hunter will probably be expecting you to do this with a for loop, so they'll have an easier time finding it if you use a for loop.
- 无论您使用什么解决方案,几乎肯定会比这更长。使用预先构建的函数只会将其隐藏在更多的掩护之下。
- 阅读您的代码的人必须弄清楚您在该非 for 循环中正在做什么。考虑到 for 循环是执行此操作的惯用方式,如果您使用 for 循环执行此操作,则更容易确定。
- 是的,有人可能会添加一些聪明的东西,但是通过避免 for 循环,您正在做一些聪明的事情。这就像故意射自己的脚以避免意外射中自己的脚。
- 单次测试也很容易捕捉到一对一的错误。鉴于您应该测试您的代码,一个逐一的错误应该很容易修复和捕获。值得注意的是:上面的代码不包含逐一错误。For 循环同样容易正确。
- 所以不要重用变量。这不是 for 循环的错。
- 同样,您使用的任何解决方案也是如此。正如我之前提到的;一个 bug 猎人可能会希望你用 for 循环来做这件事,所以如果你使用 for 循环,他们会更容易找到它。
回答by fortran
So you want to avoid loops?
所以你想避免循环?
Here you have it:
给你:
public static String repeat(String s, int times) {
if (times <= 0) return "";
else return s + repeat(s, times-1);
}
(of course I know this is ugly and inefficient, but it doesn't have loops :-p)
(当然我知道这很丑陋且效率低下,但它没有循环:-p)
You want it simpler and prettier? use jython:
你想要它更简单更漂亮吗?使用 jython:
s * 3
Edit: let's optimize it a little bit :-D
编辑:让我们稍微优化一下:-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: I've done a quick and dirty benchmark for the 4 main alternatives, but I don't have time to run it several times to get the means and plot the times for several inputs... So here's the code if anybody wants to try it:
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();
}
}
It takes 2 arguments, the first is the number of iterations (each function run with repeat times arg from 1..n) and the second is the string to repeat.
它需要 2 个参数,第一个是迭代次数(每个函数以 1..n 的重复次数 arg 运行),第二个是要重复的字符串。
So far, a quick inspection of the times running with different inputs leaves the ranking something like this (better to worse):
到目前为止,快速检查使用不同输入运行的时间会得出这样的排名(更好更糟):
- Iterative StringBuilder append (1x).
- Recursive concatenation log2 invocations (~3x).
- Recursive concatenation linear invocations (~30x).
- Iterative concatenation linear (~45x).
- 迭代 StringBuilder 追加 (1x)。
- 递归串联 log2 调用 (~3x)。
- 递归串联线性调用(~30x)。
- 迭代串联线性(~45x)。
I wouldn't ever guessed that the recursive function was faster than the for
loop :-o
我永远不会猜到递归函数比for
循环更快:-o
Have fun(ctional xD).
玩得开心(xD)。
回答by dfa
based on fortran's answer, this is a recusive version that uses a StringBuilder:
基于fortran 的回答,这是一个使用 StringBuilder 的递归版本:
public static void repeat(StringBuilder stringBuilder, String s, int times) {
if (times > 0) {
repeat(stringBuilder.append(s), s, times - 1);
}
}
public static String repeat(String s, int times) {
StringBuilder stringBuilder = new StringBuilder(s.length() * times);
repeat(stringBuilder, s, times);
return stringBuilder.toString();
}
回答by I. J. Kennedy
Here's a way to do it using only standard String functions and no explicit loops:
这是一种仅使用标准字符串函数而不使用显式循环的方法:
// create a string made up of n copies of s
repeated = String.format(String.format("%%%ds", n), " ").replace(" ",s);
回答by dfa
回答by user102008
Here is the shortest version (Java 1.5+ required):
这是最短的版本(需要 Java 1.5+):
repeated = new String(new char[n]).replace("##代码##", s);
Where n
is the number of times you want to repeat the string and s
is the string to repeat.
哪里n
是你想要重复字符串的次数,s
是要重复的字符串。
No imports or libraries needed.
不需要导入或库。