Создайте строку с n символами


есть ли способ в java создать строку с заданным числом указанного символа? В моем случае, мне нужно создать строку с 10 места. Мой текущий код:

StringBuffer outputBuffer = new StringBuffer(length);
for (int i = 0; i < length; i++){
   outputBuffer.append(" ");
}
return outputBuffer.toString();

есть ли лучший способ сделать то же самое. В частности, я хотел бы что-то быстрое (с точки зрения исполнения).

20 108

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);

в Java 8 вы можете использовать String.join:

String.join("", Collections.nCopies(n, s));

Если вы хотите только пробелы, то как насчет:

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 мс меньше при создании огромных пространств. Для меньших размеров оба результата незначительны.

но, пожалуйста, продолжайте комментировать :-)

Я не знаю никакого встроенного метода для того, о чем вы спрашиваете. Однако для небольшой фиксированной длины, такой как 10, ваш метод должен быть достаточно быстрым.