Создать строку с n символами
есть ли способ в java создать строку с указанным числом указанного символа? В моем случае, мне нужно создать строку с 10 места. Мой текущий код:
StringBuffer outputBuffer = new StringBuffer(length);
for (int i = 0; i < length; i++){
outputBuffer.append(" ");
}
return outputBuffer.toString();
есть ли лучший способ сделать то же самое. В частности, я хотел бы что-то быстрое (с точки зрения исполнения).
20 ответов
цикл for будет оптимизирован компилятором. В таких случаях, как ваш, вам не нужно заботиться об оптимизации самостоятельно. Доверять компилятору. :)
Edit: кстати, если есть способ создать строку с N пробелами, то она закодирована так же, как вы только что сделали.
вероятно, самый короткий код с помощью String
API-интерфейс, исключительно:
String space10 = new String(new char[10]).replace('', ' ');
System.out.println("[" + space10 + "]");
// prints "[ ]"
как метод, без непосредственного создания экземпляра char
:
import java.nio.CharBuffer;
/**
* Creates a string of spaces that is 'spaces' spaces long.
*
* @param spaces The number of spaces to add to the string.
*/
public String spaces( int spaces ) {
return CharBuffer.allocate( spaces ).toString().replace( '', ' ' );
}
вызвать с помощью:
System.out.printf( "[%s]%n", spaces( 10 ) );
Мда теперь, когда я думаю об этом, может быть Arrays.fill
:
char[] charArray = new char[length];
Arrays.fill(charArray, ' ');
String str = new String(charArray);
конечно, я предполагаю, что fill
метод делает то же самое, что и ваш код, поэтому он, вероятно, будет выполнять примерно то же самое, но, по крайней мере, это меньше строк.
я настоятельно рекомендую не писать цикл вручную. Вы будете делать это снова и снова в течение вашей карьеры программирования. Люди, читающие ваш код, включая вас, всегда должны тратить время, даже если это всего несколько секунд, чтобы переварить смысл цикла.
вместо использовать одна из доступных библиотек, предоставляющих код, который делает именно это, как StringUtils.repeat
С Apache Commons Lang:
StringUtils.repeat(' ', length);
таким образом, вы также не нужно беспокоиться о производительности, таким образом, все кровавые детали StringBuilder
, оптимизаций компилятора и т. д. спрятаны.
Если функция окажется такой же медленной, это будет ошибка библиотеки.
С Java 11 становится еще проще:
" ".repeat(length);
Если вы хотите только пробелы, то как насчет:
String spaces = (n==0)?"":String.format("%"+n+"s", "");
что приведет к пробелам abs(n);
Я думаю, что это меньше кода, это возможно, он использует класс Guava Joiner:
Столяр.на.)""(присоединиться(коллекций.nCopies(10, " "));
мой вклад, основанный на алгоритме быстрого возведения в степень.
/**
* Repeats the given {@link String} n times.
*
* @param str
* the {@link String} to repeat.
* @param n
* the repetition count.
* @throws IllegalArgumentException
* when the given repetition count is smaller than zero.
* @return the given {@link String} repeated n times.
*/
public static String repeat(String str, int n) {
if (n < 0)
throw new IllegalArgumentException(
"the given repetition count is smaller than zero!");
else if (n == 0)
return "";
else if (n == 1)
return str;
else if (n % 2 == 0) {
String s = repeat(str, n / 2);
return s.concat(s);
} else
return str.concat(repeat(str, n - 1));
}
я протестировал алгоритм против двух других подходов:
- обычный для цикла с помощью
String.concat()
объединить строку - обычный для цикла с помощью
StringBuilder
тестовый код (конкатенация с использованием цикла for и String.concat()
становится медленным для больших n
, поэтому я оставил его после 5-го повторение.)
/**
* Test the string concatenation operation.
*
* @param args
*/
public static void main(String[] args) {
long startTime;
String str = " ";
int n = 1;
for (int j = 0; j < 9; ++j) {
n *= 10;
System.out.format("Performing test with n=%d\n", n);
startTime = System.currentTimeMillis();
StringUtil.repeat(str, n);
System.out
.format("\tStringUtil.repeat() concatenation performed in %d milliseconds\n",
System.currentTimeMillis() - startTime);
if (j <5) {
startTime = System.currentTimeMillis();
String string = "";
for (int i = 0; i < n; ++i)
string = string.concat(str);
System.out
.format("\tString.concat() concatenation performed in %d milliseconds\n",
System.currentTimeMillis() - startTime);
} else
System.out
.format("\tString.concat() concatenation performed in x milliseconds\n");
startTime = System.currentTimeMillis();
StringBuilder b = new StringBuilder();
for (int i = 0; i < n; ++i)
b.append(str);
b.toString();
System.out
.format("\tStringBuilder.append() concatenation performed in %d milliseconds\n",
System.currentTimeMillis() - startTime);
}
}
результаты:
Performing test with n=10
StringUtil.repeat() concatenation performed in 0 milliseconds
String.concat() concatenation performed in 0 milliseconds
StringBuilder.append() concatenation performed in 0 milliseconds
Performing test with n=100
StringUtil.repeat() concatenation performed in 0 milliseconds
String.concat() concatenation performed in 1 milliseconds
StringBuilder.append() concatenation performed in 0 milliseconds
Performing test with n=1000
StringUtil.repeat() concatenation performed in 0 milliseconds
String.concat() concatenation performed in 1 milliseconds
StringBuilder.append() concatenation performed in 1 milliseconds
Performing test with n=10000
StringUtil.repeat() concatenation performed in 0 milliseconds
String.concat() concatenation performed in 43 milliseconds
StringBuilder.append() concatenation performed in 5 milliseconds
Performing test with n=100000
StringUtil.repeat() concatenation performed in 0 milliseconds
String.concat() concatenation performed in 1579 milliseconds
StringBuilder.append() concatenation performed in 1 milliseconds
Performing test with n=1000000
StringUtil.repeat() concatenation performed in 0 milliseconds
String.concat() concatenation performed in x milliseconds
StringBuilder.append() concatenation performed in 10 milliseconds
Performing test with n=10000000
StringUtil.repeat() concatenation performed in 7 milliseconds
String.concat() concatenation performed in x milliseconds
StringBuilder.append() concatenation performed in 112 milliseconds
Performing test with n=100000000
StringUtil.repeat() concatenation performed in 80 milliseconds
String.concat() concatenation performed in x milliseconds
StringBuilder.append() concatenation performed in 1107 milliseconds
Performing test with n=1000000000
StringUtil.repeat() concatenation performed in 1372 milliseconds
String.concat() concatenation performed in x milliseconds
StringBuilder.append() concatenation performed in 12125 milliseconds
вывод:
- большие
n
- использовать рекурсивный подход - для маленьких
n
- для петли имеет достаточную скорость
Как насчет этого?
char[] bytes = new char[length];
Arrays.fill(bytes, ' ');
String str = new String(bytes);
RandomStringUtils имеет положение для создания строки из заданного размера ввода. Не могу прокомментировать скорость, но это один лайнер.
RandomStringUtils.random(5,"\t");
создает выходной
\t\t\t\t \ T
предпочтительнее, если вы не хотите, чтобы увидеть \0 в коде.
в большинстве случаев вам нужны только строки до длины сертификатов, скажем, 100 пробелов. Вы можете подготовить массив строк, где номер индекса равен размеру строки, заполненной пробелом, и найти строку, если требуемая длина находится в пределах или создать ее по требованию, если она находится за пределами границы.
вы можете использовать стандартный String.format
функция для генерации N пространств.
Например:
String.format("%5c", ' ');
создает строку с 5 пробелами.
или
int count = 15;
String fifteenSpacebars = String.format("%" + count + "c", ' ');
делает строку из 15 spacebars.
если вы хотите, чтобы другой символ повторился, вы должны заменить пробелы желаемым символом:
int count = 7;
char mySymbol = '#';
System.out.println(String.format("%" + count + "c", ' ').replaceAll("\ ", "\" + mySymbol));
выход:
#######
просто замените свой StringBuffer на StringBuilder. Трудно превзойти это.
Если ваша длина большое число, вы могли бы реализовать некоторые более эффективные (но более топорно) самовывоз-appendding, дублируя длины на каждой итерации:
public static String dummyString(char c, int len) {
if( len < 1 ) return "";
StringBuilder sb = new StringBuilder(len).append(c);
int remnant = len - sb.length();
while(remnant > 0) {
if( remnant >= sb.length() ) sb.append(sb);
else sb.append(sb.subSequence(0, remnant));
remnant = len - sb.length();
}
return sb.toString();
}
кроме того, вы можете попробовать Arrays.fill()
aproach (FrustratedWithFormsDesigner'ы ответ).
вы можете заменить StringBuffer
С StringBuilder
(последний не синхронизирован, может быть быстрее в одном потоковом приложении)
и вы можете создать StringBuilder
раз, вместо того, чтобы создавать его каждый раз, когда вам это нужно.
что-то вроде этого:
class BuildString {
private final StringBuilder builder = new StringBuilder();
public String stringOf( char c , int times ) {
for( int i = 0 ; i < times ; i++ ) {
builder.append( c );
}
String result = builder.toString();
builder.delete( 0 , builder.length() -1 );
return result;
}
}
и используйте его так:
BuildString createA = new BuildString();
String empty = createA.stringOf( ' ', 10 );
если вы держите свой createA
в качестве переменной экземпляра, вы можете сэкономить время при создании экземпляров.
это не потокобезопасно, если у вас есть multi потоков, каждый поток должен иметь свою собственную копию.
для хорошей производительности объедините ответы из aznilamir и FrustratedWithFormsDesigner
private static final String BLANKS = " ";
private static String getBlankLine( int length )
{
if( length <= BLANKS.length() )
{
return BLANKS.substring( 0, length );
}
else
{
char[] array = new char[ length ];
Arrays.fill( array, ' ' );
return new String( array );
}
}
изменить размер BLANKS
в зависимости от ваших потребностей. Мой специфический BLANKS
строка имеет длину около 200 символов.
есть такой метод. Это добавляет пробелы в конце данного String
чтобы сделать данную String
к длине определенной длины.
public static String fillSpaces (String str) {
// the spaces string should contain spaces exceeding the max needed
String spaces = " ";
return str + spaces.substring(str.length());
}
учитывая, что у нас есть:
String c = "c"; // character to repeat, for empty it would be " ";
int n = 4; // number of times to repeat
String EMPTY_STRING = ""; // empty string (can be put in utility class)
Java 8 (С Помощью Stream)
String resultOne = IntStream.range(0,n)
.mapToObj(i->c).collect(Collectors.joining(EMPTY_STRING)); // cccc
Java 8 (с использованием nCopies)
String resultTwo = String.join(EMPTY_STRING, Collections.nCopies(n, c)); //cccc
простой метод, как показано ниже, также может быть использован
public static String padString(String str, int leng,char chr) {
for (int i = str.length(); i <= leng; i++)
str += chr;
return str;
}
как насчет этого?
public String fillSpaces(int len) {
/* the spaces string should contain spaces exceeding the max needed */
String spaces = " ";
return spaces.substring(0,len);
}
EDIT: я написал простой код для проверки концепции и вот что я нашел.
метод 1: добавление одного пробела в цикле:
public String execLoopSingleSpace(int len){
StringBuilder sb = new StringBuilder();
for(int i=0; i < len; i++) {
sb.append(' ');
}
return sb.toString();
}
Метод 2: Добавьте 100 пробелов и цикл, затем подстроку:
public String execLoopHundredSpaces(int len){
StringBuilder sb = new StringBuilder(" ")
.append(" ").append(" ").append(" ")
.append(" ").append(" ").append(" ")
.append(" ").append(" ").append(" ");
for (int i=0; i < len/100 ; i++) {
sb.append(" ")
.append(" ").append(" ").append(" ")
.append(" ").append(" ").append(" ")
.append(" ").append(" ").append(" ");
}
return sb.toString().substring(0,len);
}
результат, который я получаю, создавая 12,345,678 пробелов:
C:\docs\Projects> java FillSpace 12345678
method 1: append single spaces for 12345678 times. Time taken is **234ms**. Length of String is 12345678
method 2: append 100 spaces for 123456 times. Time taken is **141ms**. Length of String is 12345678
Process java exited with code 0
и для 10,000,000 пробелов:
C:\docs\Projects> java FillSpace 10000000
method 1: append single spaces for 10000000 times. Time taken is **157ms**. Length of String is 10000000
method 2: append 100 spaces for 100000 times. Time taken is **109ms**. Length of String is 10000000
Process java exited with code 0
сочетания прямого распределения и итерации всегда занимает меньше времени, на в среднем 60ms меньше при создании огромных пространств. Для меньших размеров оба результата незначительны.
но, пожалуйста, продолжайте комментировать :-)
Я не знаю встроенного метода для того, о чем вы спрашиваете. Однако для небольшой фиксированной длины, такой как 10, ваш метод должен быть достаточно быстрым.