Ответ 1
Просто используйте класс StringUtils из apache commons lang. У вас есть метод leftPad:
StringUtils.leftPad("foobar", 10, '*'); // Returns "****foobar"
Я проверял другие вопросы; этот вопрос фокусируется на наиболее эффективном решении этого конкретного вопроса.
Иногда вы хотите создать новую строку с указанной длиной и с символом по умолчанию, заполняющим всю строку.
т.е. было бы здорово, если бы вы могли сделать 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 для этого.
У кого-нибудь есть лучшее решение?
Просто используйте класс StringUtils из apache commons lang. У вас есть метод leftPad:
StringUtils.leftPad("foobar", 10, '*'); // Returns "****foobar"
Apache Commons Lang (вероятно, достаточно полезный для того, чтобы быть на пути к классу любого нетривиального проекта) имеет StringUtils.repeat():
String filled = StringUtils.repeat("*", 10);
Легко!
Не нужно делать цикл и использовать только стандартные классы библиотеки 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
.
Некоторые возможные решения.
Это создает строку с длиной "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());
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();
}
Что не так?
с помощью Dollar прост:
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 вместо 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);
}
}
Еще одно примечание: кажется, что все общедоступные способы создания нового экземпляра 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);