Как StringBuilder в Java позволяет избегать создания промежуточных объектов?

«Как StringBuilder в Java позволяет избегать создания промежуточных объектов?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

StringBuilder избегает создания промежуточных объектов строк за счет использования изменяемого (mutable) внутреннего буфера (массива символов char[]).

Проблема конкатенации строк (+):

Каждая операция + со строками создает новый объект String, так как строки в Java неизменяемы (immutable). Это ведет к большим накладным расходам при множественных операциях.

String result = "";
for (int i = 0; i < 1000; i++) {
    // На КАЖДОЙ итерации создается новый String
    result = result + i; // Плохо для производительности
}

Решение через StringBuilder:

  1. Внутренний буфер: StringBuilder работает с одним массивом char[].
  2. Изменение на месте: Методы append(), insert(), replace() модифицируют этот буфер.
  3. Динамическое расширение: При нехватке места буфер автоматически увеличивается (обычно по формуле новая_длина = старая_длина * 2 + 2).
  4. Единый объект результата: Итоговый String создается только один раз при вызове toString().
StringBuilder sb = new StringBuilder(); // Создается внутренний буфер
for (int i = 0; i < 1000; i++) {
    // Данные добавляются в существующий буфер
    sb.append(i); // Промежуточные объекты String не создаются
}
String result = sb.toString(); // Создается финальный String

Ключевое отличие: StringBuilder выполняет операции O(n) по времени в худшем случае (из-за копирования при расширении буфера), в то время как наивная конкатенация в цикле имеет сложность O(n²) из-за постоянного копирования данных в новые строки.