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



этот вопрос уже есть ответ здесь:



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



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



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



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



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



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.



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

901   17  

17 ответов:

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

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

легко!

просто используйте класс StringUtils из Apache commons lang. У вас есть leftPad способ:

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

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

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

это создает строку с длиной раз' 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, ограничивает выходные данные по длине и собирает результаты со строковым столяром (new школа.)

String s = Stream.generate(() -> String.valueOf(charToFill)).limit(length).collect(Collectors.joining());
char[] chars = new char[10];
Arrays.fill(chars, '*');
String text = new String(chars);

решение с помощью Google Guava

String filled = Strings.repeat("*", 10);
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();
}

что не так?

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

шаблон строки = "####################################";

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

С помощью доллар просто:

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

решение с помощью 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);
}

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

теперь за инженерное решение. Во многих (ты не во всех) случаях вы можете использовать CharSequence вместо строки.

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

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

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

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

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

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

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

это вернет abcde.

Mi решение:

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

вывод :

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

попробуйте эту работу

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

        }
            stringy =StringUtils.toAsciiString(buffer);

вы можете использовать цикл while следующим образом:

String text = "Hello";
while (text.length() < 10) { text += "*"; }
System.out.println(text);

даст вам:

Hello*****

или получить тот же результат с помощью пользовательского метода:

    public static String extendString(String text, String symbol, Integer len) {
        while (text.length() < len) { text += symbol; }
        return text;
    }

тогда просто звоните:

extendString("Hello", "*", 10)

также может быть хорошей идеей установить проверку длины, чтобы предотвратить бесконечный цикл.

в Java 11, у вас есть repeat:

String s = " ";
s = s.repeat(1);

(хотя на момент написания статьи еще может измениться)

Comments

    Ничего не найдено.