Какие есть способы конкатенации строк в Java и какой наиболее эффективен?

Ответ

Конкатенация строк — это операция объединения двух или более строк в одну. В Java существует несколько способов, различающихся по производительности и удобству.

1. Оператор + (внутри цикла — неэффективно):

  • Прост и читаем для небольшого числа конкатенаций.
  • Под капотом компилятор преобразует "Hello" + " " + name в new StringBuilder().append("Hello").append(" ").append(name).toString().
  • Проблема: В циклах на каждой итерации создается новый StringBuilder, что ведет к O(n²) сложности.

    // ХОРОШО для простых случаев:
    String greeting = "Hello, " + userName + "!";
    
    // ПЛОХО для циклов:
    String result = "";
    for (String str : list) {
       result += str; // Создается новый StringBuilder на каждом шаге!
    }

2. Метод String.concat(String str):

  • Чуть эффективнее + для двух строк, но также создает новый объект String.
  • Неудобен для цепочек из более чем двух строк.
    String result = "Hello".concat(" ").concat("World");

3. StringBuilder (НЕ потокобезопасный, самый быстрый):

  • Используйте для конкатенации в циклах или при множественных операциях.
  • Изменяемый, не создает промежуточных объектов String.
    StringBuilder sb = new StringBuilder();
    for (String str : largeList) {
       sb.append(str);
    }
    String result = sb.toString(); // Единое преобразование в String

4. StringBuffer (потокобезопасный, медленнее StringBuilder):

  • Аналогичен StringBuilder, но с синхронизированными методами.
  • Используйте, только если объект доступен из нескольких потоков (редкий случай).

5. String.join() и StringJoiner (Java 8+):

  • Идеально для объединения коллекции строк с разделителем.
    String result = String.join(", ", "Apple", "Banana", "Orange");
    // Или
    StringJoiner joiner = new StringJoiner(", ", "[", "]");
    joiner.add("Apple").add("Banana");
    String result = joiner.toString(); // "[Apple, Banana]"

Рекомендация: Для одноразовой конкатенации 2-3 строк используйте +. Для конкатенации в циклах или при построении сложной строки всегда используйте StringBuilder.

Ответ 18+ 🔞

А, ну ты смотри, опять про эти строки в Java! Ну, блядь, классика жанра, как эти ваши "Hello, World!" собирать, чтобы не просрать всю производительность в трубу. Слушай сюда, я тебе сейчас по-простому, на пальцах, разложу, а то у некоторых от этого + в цикле уже глаза на лоб лезут.

1. Оператор + — он как дешёвая водка: с одного раза норм, а если уж в запой, то утром будет овердохуища проблем.

  • С виду — красавчик, простой и понятный. Компилятор-то умный, он для "Привет, " + username + "!" сам StringBuilder под капотом смастерит.
  • А вот если его в цикл засунуть — тут-то и начинается пиздец. На каждом витке, блядь, новый StringBuilder рождается, старый на помойку. Сложность получается O(n²), то есть если строк много — твоя программа будет думать, как ленивая мартышлюшка в зоопарке.

    // Так — можно, для разок.
    String приветствие = "Ну здарова, " + колян + "!";
    
    // А вот так — категорически нет, если не хочешь, чтобы всё накрылось медным тазом.
    String итог = "";
    for (String слово : списокСлов) {
       итог += слово; // Каждый раз новый StringBuilder, ёпта! Пиздец!
    }

2. Метод String.concat(...) — типа продвинутый, но по сути такой же одноразовый.

  • Чуть шустрее плюса для двух строк, но тоже новый объект лепит. Для цепочки из трёх штук уже неудобно — пиздопроебибна получается.
    String итог = "Привет".concat(" ").concat("Мир"); // Ну, так себе затея.

3. StringBuilder — вот это, блядь, наш бронепоезд! (НЕ для нескольких потоков, зато быстрее всех).

  • Вот его и тащи в цикл, без всяких раздумий. Мужик изменяемый, не порождает тонны мусора. Собирает всё в кучу, а потом одним махом в строку превращает — красота!
    StringBuilder sb = new StringBuilder(); // Родил один раз.
    for (String слово : огромныйСписок) {
       sb.append(слово); // Просто добавляем, нихуя не создаём.
    }
    String итог = sb.toString(); // И на тебе — готовый паровоз!

4. StringBuffer — это тот же StringBuilder, но в бронежилете (потокобезопасный, поэтому тормознутый).

  • Бери только если реально из нескольких потоков будут одновременно в него хуярить. А такое, честно, бывает редко — обычно это overengineering, ёперный театр.

5. String.join() и StringJoiner (Java 8+) — спецназ для склейки с разделителем.

  • Хочешь слова через запятую собрать или в квадратные скобки запихнуть? Вот твой инструмент. Удобно, элегантно.
    String списокПокупок = String.join(", ", "Хлеб", "Молоко", "Пиво");
    // Или с прибамбасами:
    StringJoiner joiner = new StringJoiner(", ", "[", "]");
    joiner.add("Яблоко").add("Груша");
    String итог = joiner.toString(); // "[Яблоко, Груша]"

Итог, блядь, простой: Разово склеил пару строк — + и не парься. Запустил цикл или строишь что-то большое — хватай StringBuilder и не мудри. Всё остальное — от лукавого или для очень специфичных случаев.