Создайте строку с 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. Трудно превзойти это.
Если ваша длина большое число, вы можете реализовать некоторые более эффективные (но более неуклюжий) самоприсоединение, дублирование длины в каждой итерации:
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()
подход ( 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
как переменная экземпляра, вы можете сэкономить время на создании экземпляров.это не потокобезопасно, если у вас есть несколько потоков, каждый поток должен иметь свою собственную копию.
для хорошей работы, объединить ответы от 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
сочетания прямого распределения и итерации всегда занимает меньше времени, на в среднем 60 мс меньше при создании огромных пространств. Для меньших размеров оба результата незначительны.
но, пожалуйста, продолжайте комментировать :-)