Как я могу эффективно использовать StringBuilder?

Раньше я всегда использовал printf для форматирования печати на консоли, но текущее задание (создание отчета о счете) требует, чтобы мы использовали StringBuilder, но я понятия не имею, как это сделать, просто не используя "" для каждого промежуток необходим. Например ... я должен это распечатать

Invoice   Customer                                          Salesperson                      Subtotal        Fees       Taxes    Discount       Total
INV001    Company                                           Eccleston, Chris              $   2357.60 $     40.00 $    190.19 $  -282.91 $   2304.88

Но я не знаю, как заставить все выровняться с помощью StringBuilder. Любой совет?


person Ryan Dorman    schedule 14.10.2015    source источник
comment
вы пробовали какой-то код ... если да, поделитесь, если нет, пожалуйста ...   -  person Jos    schedule 14.10.2015
comment
StringBuilder предназначен для эффективного объединения строк. Он не предназначен для форматирования строк. В Java есть String.format, который позволяет вам printf форматировать стиль. Вам не разрешено использовать это?   -  person sh0rug0ru    schedule 14.10.2015


Ответы (1)


StringBuilder стремится снизить накладные расходы, связанные с созданием строк.

Как вы можете знать или не знать, строки неизменяемы. Что это значит что-то вроде

String a = "foo";
String b = "bar";
String c = a + b;
String d = c + c;

создает новую строку для каждой строки. Если все, что нас беспокоит, это последняя строка d, строка со строкой c тратит впустую пространство, потому что создает новый String объект, когда он нам не нужен.

Построитель строк просто задерживает фактическое построение объекта String до тех пор, пока вы не вызовете .toString(). В этот момент он преобразует внутренний char[] в фактическую строку.

Возьмем другой пример.

String foo() {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 100; i++)
       sb.append(i);
    return sb.toString();
}

Здесь мы создаем только одну строку. StringBuilder будет отслеживать символы, которые вы добавили в свою строку, во внутреннем char[] value. Обратите внимание, что value.length обычно будет больше, чем общее количество символов, которые вы добавили в свой StringBuilder, но value может не хватить места для того, что вы добавляете, если строка, которую вы создаете, станет слишком большой. Когда это произойдет, он изменит размер, что означает просто замену value на больший char[] и копирование старых значений в новый массив вместе с символами того, что вы добавили.

Наконец, когда вы вызываете sb.toString(), StringBuilder вызовет конструктор String, который принимает аргумент char[].

Это означает, что был создан только один String объект, и нам нужно было достаточно памяти только для нашего char[] и для изменения его размера.

Сравните со следующим:

String foo() {
    String toReturn = "";
    for (int i = 0; i < 100; i++)
       toReturn += "" + i;
    toReturn;
}

Здесь у нас создан 101 строковый объект (может быть, больше, я не уверен). Но нам нужен был только один! Это означает, что при каждом вызове мы удаляем исходную представленную строку toReturn и создаем другую строку.

В частности, для большой строки это очень дорого, потому что при каждом вызове вам нужно сначала получить столько памяти, сколько требуется новой строке, и избавиться от того объема памяти, который был у старой строки. Это не имеет большого значения, когда все делается кратко, но когда вы работаете с целыми файлами, это легко может стать проблемой.

Вкратце: если вы работаете с добавлением / удалением информации до завершения вывода: используйте StringBuilder. Если ваши строки очень короткие, я думаю, что нормально просто объединить их для удобства, но вам решать, что такое «короткие».

person Joseph Nields    schedule 14.10.2015