This question already has an answer here:
这个问题在这里已有答案:
- Simple way to repeat a String in java 29 answers
- 在Java 29答案中重复String的简单方法
I did check the other questions; this question has its focus on solving this particular question the most efficient way.
我确实检查了其他问题;这个问题的重点是以最有效的方式解决这个特定问题。
Sometimes you want to create a new string with a specified length, and with a default character filling the entire string.
有时您希望创建一个具有指定长度的新字符串,并使用填充整个字符串的默认字符。
ie, it would be cool if you could do new String(10, '*')
and create a new String from there, with a length of 10 characters all having a *.
也就是说,如果你可以做新的String(10,'*')并从那里创建一个新的字符串,长度为10个字符都有*,那就太酷了。
Because such a constructor does not exist, and you cannot extend from String, you have either to create a wrapper class or a method to do this for you.
因为这样的构造函数不存在,并且您无法从String扩展,所以您要么创建一个包装类,要么为您执行此操作的方法。
At this moment I am using this:
此刻我正在使用这个:
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);
}
It still lacks any checking (ie, when length is 0 it will not work). I am constructing the array first because I believe it is faster than using string concatination or using a StringBuffer to do so.
它仍然没有任何检查(即,当长度为0时,它将不起作用)。我首先构造数组,因为我相信它比使用字符串连接或使用StringBuffer更快。
Anyone else has a better sollution?
其他人有更好的解决方案吗?
17 个解决方案
#1
74
Apache Commons Lang (probably useful enough to be on the classpath of any non-trivial project) has StringUtils.repeat():
Apache Commons Lang(可能对任何非平凡项目的类路径都很有用)具有StringUtils.repeat():
String filled = StringUtils.repeat("*", 10);
Easy!
简单!
#2
99
Simply use the StringUtils class from apache commons lang project. You have a leftPad method:
只需使用apache commons lang项目中的StringUtils类。你有一个leftPad方法:
StringUtils.leftPad("foobar", 10, '*'); // Returns "****foobar"
#3
52
No need to do the loop, and using just standard Java library classes:
无需执行循环,只使用标准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 "";
}
As you can see, I also added suitable code for the length == 0
case.
如您所见,我还为长度== 0的情况添加了合适的代码。
#4
28
Some possible solutions.
一些可能的解决方
This creates a String with length-times '0' filled and replaces then the '0' with the charToFill (old school).
这将创建一个填充长度为“0”的字符串,然后使用charToFill(旧学校)替换“0”。
String s = String.format("%0" + length + "d", 0).replace('0', charToFill);
This creates a List containing length-times Strings with charToFill and then joining the List into a String.
这将创建一个List,其中包含使用charToFill的长度字符串,然后将List连接到String中。
String s = String.join("", Collections.nCopies(length, String.valueOf(charToFill)));
This creates a unlimited java8 Stream with Strings with charToFill, limits the output to length and collects the results with a String joiner (new school).
这将使用charToFill创建带有字符串的无限java8 Stream,将输出限制为length并使用String joiner(新学校)收集结果。
String s = Stream.generate(() -> String.valueOf(charToFill)).limit(length).collect(Collectors.joining());
#5
16
char[] chars = new char[10];
Arrays.fill(chars, '*');
String text = new String(chars);
#7
5
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();
}
What is wrong?
哪里不对?
#8
5
To improve performance you could have a single predefined sting if you know the max length like:
为了提高性能,如果您知道最大长度,则可以使用单个预定义的sting:
String template = "####################################";
String template =“####################################”;
And then simply perform a substring once you know the length.
然后在知道长度后简单地执行子串。
#9
4
using Dollar is simple:
使用Dollar很简单:
String filled = $("=").repeat(10).toString(); // produces "=========="
#10
4
Solution using Google Guava, since I prefer it to Apache Commons-Lang:
使用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);
}
#11
4
The above is fine. Do you mind if I ask you a question - Is this causing you a problem? It seams to me you are optimizing before you know if you need to.
以上是好的。你介意我问你一个问题 - 这会导致你出问题吗?在您知道是否需要之前,它会对您进行优化。
Now for my over engineered solution. In many (thou not all) cases you can use CharSequence instead of a String.
现在为我的工程解决方案。在许多(不是全部)情况下,您可以使用CharSequence而不是String。
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);
}
}
#12
2
One extra note: it seems that all public ways of creating a new String
instance involves necessarily the copy of whatever buffer you are working with, be it a char[]
, a StringBuffer
or a StringBuilder
. From the String
javadoc (and is repeated in the respective toString
methods from the other classes):
另外需要注意的是:似乎所有创建新String实例的公共方法都必然包含您正在使用的任何缓冲区的副本,无论是char [],StringBuffer还是StringBuilder。从String javadoc(并在其他类的相应toString方法中重复):
The contents of the character array are copied; subsequent modification of the character array does not affect the newly created string.
复制字符数组的内容;后续修改字符数组不会影响新创建的字符串。
So you'll end up having a possibly big memory copy operation after the "fast filling" of the array. The only solution that may avoid this issue is the one from @mlk, if you can manage working directly with the proposed CharSequence
implementation (what may be the case).
因此,在“快速填充”数组之后,您最终会有一个可能很大的内存复制操作。可以避免此问题的唯一解决方案是来自@mlk的解决方案,如果您可以管理直接使用建议的CharSequence实现(可能是这种情况)。
PS: I would post this as a comment but I don't have enough reputation to do that yet.
PS:我会将此作为评论发布,但我还没有足够的声誉来做到这一点。
#13
1
Try this Using the substring(int start, int end); method
试试这个使用substring(int start,int end);方法
String myLongString = "abcdefghij";
if (myLongString .length() >= 10)
String shortStr = myLongString.substring(0, 5)+ "...";
this will return abcde.
这将返回abcde。
#14
1
Mi solution :
米解决方案:
pw = "1321";
if (pw.length() < 16){
for(int x = pw.length() ; x < 16 ; x++){
pw += "*";
}
}
The output :
输出 :
1321************
#15
0
Try this jobber
试试这个职业
String stringy =null;
byte[] buffer = new byte[100000];
for (int i = 0; i < buffer.length; i++) {
buffer[i] =0;
}
stringy =StringUtils.toAsciiString(buffer);
#16
0
You can use a while loop like this:
您可以像这样使用while循环:
String text = "Hello";
while (text.length() < 10) { text += "*"; }
System.out.println(text);
Will give you:
会给你:
Hello*****
Or get the same result with a custom method:
或者使用自定义方法获得相同的结果:
public static String extendString(String text, String symbol, Integer len) {
while (text.length() < len) { text += symbol; }
return text;
}
Then just call:
然后打电话:
extendString("Hello", "*", 10)
It may also be a good idea to set a length check to prevent infinite loop.
设置长度检查以防止无限循环也是一个好主意。
#17
0
In Java 11, you have repeat
:
在Java 11中,您重复:
String s = " ";
s = s.repeat(1);
(Although at the time of writing still subject to change)
(虽然在撰写本文时仍有待更改)
#1
74
Apache Commons Lang (probably useful enough to be on the classpath of any non-trivial project) has StringUtils.repeat():
Apache Commons Lang(可能对任何非平凡项目的类路径都很有用)具有StringUtils.repeat():
String filled = StringUtils.repeat("*", 10);
Easy!
简单!
#2
99
Simply use the StringUtils class from apache commons lang project. You have a leftPad method:
只需使用apache commons lang项目中的StringUtils类。你有一个leftPad方法:
StringUtils.leftPad("foobar", 10, '*'); // Returns "****foobar"
#3
52
No need to do the loop, and using just standard Java library classes:
无需执行循环,只使用标准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 "";
}
As you can see, I also added suitable code for the length == 0
case.
如您所见,我还为长度== 0的情况添加了合适的代码。
#4
28
Some possible solutions.
一些可能的解决方
This creates a String with length-times '0' filled and replaces then the '0' with the charToFill (old school).
这将创建一个填充长度为“0”的字符串,然后使用charToFill(旧学校)替换“0”。
String s = String.format("%0" + length + "d", 0).replace('0', charToFill);
This creates a List containing length-times Strings with charToFill and then joining the List into a String.
这将创建一个List,其中包含使用charToFill的长度字符串,然后将List连接到String中。
String s = String.join("", Collections.nCopies(length, String.valueOf(charToFill)));
This creates a unlimited java8 Stream with Strings with charToFill, limits the output to length and collects the results with a String joiner (new school).
这将使用charToFill创建带有字符串的无限java8 Stream,将输出限制为length并使用String joiner(新学校)收集结果。
String s = Stream.generate(() -> String.valueOf(charToFill)).limit(length).collect(Collectors.joining());
#5
16
char[] chars = new char[10];
Arrays.fill(chars, '*');
String text = new String(chars);
#6
#7
5
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();
}
What is wrong?
哪里不对?
#8
5
To improve performance you could have a single predefined sting if you know the max length like:
为了提高性能,如果您知道最大长度,则可以使用单个预定义的sting:
String template = "####################################";
String template =“####################################”;
And then simply perform a substring once you know the length.
然后在知道长度后简单地执行子串。
#9
4
using Dollar is simple:
使用Dollar很简单:
String filled = $("=").repeat(10).toString(); // produces "=========="
#10
4
Solution using Google Guava, since I prefer it to Apache Commons-Lang:
使用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);
}
#11
4
The above is fine. Do you mind if I ask you a question - Is this causing you a problem? It seams to me you are optimizing before you know if you need to.
以上是好的。你介意我问你一个问题 - 这会导致你出问题吗?在您知道是否需要之前,它会对您进行优化。
Now for my over engineered solution. In many (thou not all) cases you can use CharSequence instead of a String.
现在为我的工程解决方案。在许多(不是全部)情况下,您可以使用CharSequence而不是String。
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);
}
}
#12
2
One extra note: it seems that all public ways of creating a new String
instance involves necessarily the copy of whatever buffer you are working with, be it a char[]
, a StringBuffer
or a StringBuilder
. From the String
javadoc (and is repeated in the respective toString
methods from the other classes):
另外需要注意的是:似乎所有创建新String实例的公共方法都必然包含您正在使用的任何缓冲区的副本,无论是char [],StringBuffer还是StringBuilder。从String javadoc(并在其他类的相应toString方法中重复):
The contents of the character array are copied; subsequent modification of the character array does not affect the newly created string.
复制字符数组的内容;后续修改字符数组不会影响新创建的字符串。
So you'll end up having a possibly big memory copy operation after the "fast filling" of the array. The only solution that may avoid this issue is the one from @mlk, if you can manage working directly with the proposed CharSequence
implementation (what may be the case).
因此,在“快速填充”数组之后,您最终会有一个可能很大的内存复制操作。可以避免此问题的唯一解决方案是来自@mlk的解决方案,如果您可以管理直接使用建议的CharSequence实现(可能是这种情况)。
PS: I would post this as a comment but I don't have enough reputation to do that yet.
PS:我会将此作为评论发布,但我还没有足够的声誉来做到这一点。
#13
1
Try this Using the substring(int start, int end); method
试试这个使用substring(int start,int end);方法
String myLongString = "abcdefghij";
if (myLongString .length() >= 10)
String shortStr = myLongString.substring(0, 5)+ "...";
this will return abcde.
这将返回abcde。
#14
1
Mi solution :
米解决方案:
pw = "1321";
if (pw.length() < 16){
for(int x = pw.length() ; x < 16 ; x++){
pw += "*";
}
}
The output :
输出 :
1321************
#15
0
Try this jobber
试试这个职业
String stringy =null;
byte[] buffer = new byte[100000];
for (int i = 0; i < buffer.length; i++) {
buffer[i] =0;
}
stringy =StringUtils.toAsciiString(buffer);
#16
0
You can use a while loop like this:
您可以像这样使用while循环:
String text = "Hello";
while (text.length() < 10) { text += "*"; }
System.out.println(text);
Will give you:
会给你:
Hello*****
Or get the same result with a custom method:
或者使用自定义方法获得相同的结果:
public static String extendString(String text, String symbol, Integer len) {
while (text.length() < len) { text += symbol; }
return text;
}
Then just call:
然后打电话:
extendString("Hello", "*", 10)
It may also be a good idea to set a length check to prevent infinite loop.
设置长度检查以防止无限循环也是一个好主意。
#17
0
In Java 11, you have repeat
:
在Java 11中,您重复:
String s = " ";
s = s.repeat(1);
(Although at the time of writing still subject to change)
(虽然在撰写本文时仍有待更改)