← Назад к вопросам

Зачем нужен StringBuilder?

1.3 Junior🔥 171 комментариев
#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

StringBuilder в Java

Зачем он нужен

StringBuilder нужен для эффективного конкатенирования строк. В Java строки (String) — это неизменяемые объекты (immutable). Каждая операция конкатенации создаёт новый объект String, что приводит к избыточному использованию памяти и замедлению работы.

Проблема обычной конкатенации

// Неэффективно
String result = "";
for (int i = 0; i < 10000; i++) {
    result = result + "Item " + i + ", ";
}

Что происходит в памяти:

  1. Первая итерация: создаётся String ""
  2. Вторая: создаётся новый String ("" + "Item 0, ") = "Item 0, "
  3. Третья: создаётся новый String ("Item 0, " + "Item 1, ") = "Item 0, Item 1, "
  4. И так далее...

В результате: 10000 объектов String в памяти, каждый содержит всё, что было раньше + новую строку.

Решение: StringBuilder

// Эффективно
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
    sb.append("Item ").append(i).append(", ");
}
String result = sb.toString();

Как работает StringBuilder:

  • Это изменяемый объект (mutable)
  • Имеет внутренний буфер (char[] array)
  • При append() просто добавляет символы в буфер
  • Когда буфер переполняется, размер автоматически увеличивается
  • toString() создаёт String один раз в конце

Производительность

long start = System.currentTimeMillis();

// Способ 1: конкатенация (медленно)
String result1 = "";
for (int i = 0; i < 10000; i++) {
    result1 = result1 + "Item " + i;
}
// ~5000ms (может зависеть от JVM)

// Способ 2: StringBuilder (быстро)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
    sb.append("Item ").append(i);
}
String result2 = sb.toString();
// ~5ms

long end = System.currentTimeMillis();
System.out.println("Разница: " + (end - start) + "ms");

StringBuilder vs StringBuffer

// StringBuilder - однопоточный (быстрее)
StringBuilder sb = new StringBuilder();
sb.append("Hello").append(" ").append("World");

// StringBuffer - многопоточный (медленнее, synchronized)
StringBuffer sbuf = new StringBuffer();
sbuf.append("Hello").append(" ").append("World");

Правило: Используй StringBuilder для однопоточного кода, StringBuffer только если нужна синхронизация (редко в современном коде).

Основные методы StringBuilder

StringBuilder sb = new StringBuilder();

// append() - добавляет в конец
sb.append("Hello").append(" ").append("World");

// insert() - вставляет в позицию
sb.insert(5, "Beautiful ");  // "HelloBeautiful World"

// delete() - удаляет символы
sb.delete(5, 15);  // "Hello World"

// deleteCharAt() - удаляет один символ
sb.deleteCharAt(4);  // "HellWorld"

// replace() - заменяет диапазон
sb.replace(0, 5, "Hi");  // "Hi World"

// reverse() - разворот строки
sb.reverse();  // "dlroW Hi"

// setLength() - устанавливает длину
sb.setLength(2);  // "dl"

// toString() - преобразование в String
String result = sb.toString();

// capacity() - размер буфера
int capacity = sb.capacity();  // >16 (начальный размер)

// length() - текущая длина
int length = sb.length();

Практические примеры

1. Построение SQL запроса:

public String buildQuery(List<String> columns) {
    StringBuilder query = new StringBuilder();
    query.append("SELECT ");
    
    for (int i = 0; i < columns.size(); i++) {
        query.append(columns.get(i));
        if (i < columns.size() - 1) {
            query.append(", ");
        }
    }
    
    query.append(" FROM users");
    return query.toString();
}

2. Логирование:

public String formatLog(String level, String message, Object... args) {
    StringBuilder log = new StringBuilder();
    log.append("[")
        .append(new Date())
        .append("] ")
        .append(level)
        .append(" - ")
        .append(message);
    
    for (Object arg : args) {
        log.append(" ").append(arg);
    }
    
    return log.toString();
}

3. CSV генерация:

public String generateCSV(List<Map<String, String>> records) {
    StringBuilder csv = new StringBuilder();
    
    for (Map<String, String> record : records) {
        for (String value : record.values()) {
            csv.append('"').append(value).append('"').append(",");
        }
        csv.setLength(csv.length() - 1);  // Удалить последнюю запятую
        csv.append("\n");
    }
    
    return csv.toString();
}

Интересный факт: Компилятор оптимизирует конкатенацию

// Компилятор видит это:
String str = "Hello" + " " + "World";

// И автоматически преобразует в:
String str = new StringBuilder()
    .append("Hello")
    .append(" ")
    .append("World")
    .toString();

НО это работает только если компилятор может это увидеть на этапе компиляции! Если переменные — это значит, компилятор не знает значения и не может оптимизировать.

Когда использовать StringBuilder

  1. Циклы с конкатенацией — всегда!
  2. Построение сложных строк — логи, SQL, JSON
  3. Обработка больших текстов — файлы, потоки данных
  4. Строковые трансформации — замены, удаления, вставки

Когда это не нужно

  • Одна-две операции конкатенации
  • Простое форматирование (используй String.format())
  • String.join() для соединения коллекций (уже оптимизирован)

Вывод

StringBuilder — это основной инструмент для эффективной работы со строками в Java. Помни: String — immutable, StringBuilder — mutable. Выбор правильного инструмента может улучшить производительность приложения в сотни раз.

Зачем нужен StringBuilder? | PrepBro