Java. Создайте новый экземпляр String с указанной длиной и заполните конкретным символом. Лучшее решение?

Я проверял другие вопросы; этот вопрос фокусируется на наиболее эффективном решении этого конкретного вопроса.

Иногда вы хотите создать новую строку с указанной длиной и с символом по умолчанию, заполняющим всю строку.

т.е. было бы здорово, если бы вы могли сделать new String(10, '*') и создать новую строку оттуда с длиной в 10 символов, имеющих *.

Поскольку такой конструктор не существует и вы не можете распространяться из String, вам нужно либо создать класс-оболочку, либо метод для этого.

В данный момент я использую это:

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

У него все еще нет проверки (т.е. когда длина равна 0, она не будет работать). Я сначала создаю массив, потому что считаю, что это быстрее, чем использование конкатенации строк или использование StringBuffer для этого.

У кого-нибудь есть лучшее решение?

Ответ 1

Просто используйте класс StringUtils из apache commons lang. У вас есть метод leftPad:

StringUtils.leftPad("foobar", 10, '*'); // Returns "****foobar"

Ответ 2

Apache Commons Lang (вероятно, достаточно полезный для того, чтобы быть на пути к классу любого нетривиального проекта) имеет StringUtils.repeat():

String filled = StringUtils.repeat("*", 10);

Легко!

Ответ 3

Не нужно делать цикл и использовать только стандартные классы библиотеки 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 "";
}

Как вы можете видеть, я также добавил подходящий код для случая length == 0.

Ответ 4

Некоторые возможные решения.

Это создает строку с длиной "0", заполненную и заменяющую "0" на charToFill (старая школа).

String s = String.format("%0" + length + "d", 0).replace('0', charToFill);

Это создает список, содержащий строки с длиной строки с charToFill, а затем объединение списка в строку.

String s = String.join("", Collections.nCopies(length, String.valueOf(charToFill)));

Это создает неограниченный поток java8 с строками с charToFill, ограничивает вывод до длины и собирает результаты с помощью String joiner (новая школа).

String s = Stream.generate(() -> String.valueOf(charToFill)).limit(length).collect(Collectors.joining());

Ответ 5

char[] chars = new char[10];
Arrays.fill(chars, '*');
String text = new String(chars);

Ответ 6

Чтобы повысить производительность, у вас может быть одно предопределенное жало, если вы знаете максимальную длину, например:

Строковый шаблон = "#######################################"

А затем просто выполните подстроку, как только вы знаете длину.

Ответ 7

Решение с использованием Google Guava

String filled = Strings.repeat("*", 10);

Ответ 8

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

Что не так?

Ответ 9

с помощью Dollar прост:

String filled = $("=").repeat(10).toString(); // produces "=========="

Ответ 10

Решение с помощью 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

Это хорошо. Не возражаете, если я задам вам вопрос - это вызывает у вас проблему? Он швыряет меня, вы оптимизируете, прежде чем знаете, если вам нужно.

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

Еще одно примечание: кажется, что все общедоступные способы создания нового экземпляра String включают в себя обязательную копию любого буфера, с которым вы работаете, будь то char[], a StringBuffer или StringBuilder. Из String javadoc (и повторяется в соответствующих методах toString из других классов):

Содержимое массива символов копируется; последующая модификация массив символов не влияет вновь созданная строка.

Таким образом, вы получите операцию копирования большой памяти после "быстрого заполнения" массива. Единственным решением, которое может избежать этой проблемы, является одно из @mlk, если вы можете напрямую работать с предлагаемой реализацией CharSequence (что может быть).

PS: Я бы опубликовал это как комментарий, но пока у меня недостаточно репутации.

Ответ 13

Попробуйте это с помощью подстроки (int start, int end); Метод

String myLongString = "abcdefghij";
if (myLongString .length() >= 10)
String shortStr = myLongString.substring(0, 5)+ "...";

это вернет abcde.

Ответ 14

Mi решение:

  pw = "1321";
    if (pw.length() < 16){
      for(int x = pw.length() ; x < 16 ; x++){
        pw  += "*";
      }
    }

Выход:

1321************

Ответ 15

Попробуйте использовать этот товар

String stringy =null;
 byte[] buffer =  new byte[100000];
            for (int i = 0; i < buffer.length; i++) {
            buffer[i] =0;

        }
            stringy =StringUtils.toAsciiString(buffer);