Java Academy · Lekcja

StringBuilder do wydajnego łączenia

Używaj StringBuilder do wydajnego tworzenia łańcuchów znaków wewnątrz pętli i przy złożonym formatowaniu.

Lekcja 2 z 413 kroki

StringBuilder do wydajnego łączenia to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Java Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Java Academy zawiera 4 lekcji w sumie.

StringBuilder do wydajnej konkatenacji

StringBuilder to mutowalna alternatywa dla String, przeznaczona do stopniowego budowania tekstu. Pozwala uniknąć tworzenia wielu pośrednich obiektów String.

StringBuilder a konkatenacja String

Podczas łączenia wielu łańcuchów znaków, zwłaszcza w pętlach, StringBuilder jest znacznie szybszy, ponieważ modyfikuje wewnętrzny bufor znaków zamiast tworzyć nowe obiekty.

// Inefficient: creates a new String every iteration
String result = "";
for (int i = 0; i < 1000; i++) {
    result += i + ","; // 1000 new String objects!
}

// Efficient: StringBuilder uses a resizable char buffer
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i).append(',');
}
String efficient = sb.toString(); // one final String created

API StringBuilder

Najważniejsze metody: append, insert, delete, replace, reverse, toString, length, charAt, setCharAt.

StringBuilder sb = new StringBuilder("Hello");

sb.append(", World");     // Hello, World
sb.insert(5, "!");        // Hello!, World
sb.delete(5, 6);           // Hello, World
sb.replace(7, 12, "Java"); // Hello, Java
sb.reverse();               // avaJ ,olleH
sb.reverse();               // Hello, Java

System.out.println(sb);         // Hello, Java
System.out.println(sb.length()); // 11
System.out.println(sb.charAt(0)); // H

Łączenie wywołań append

Wszystkie metody append i inne metody mutujące zwracają this, co umożliwia płynne łączenie wywołań.

StringBuilder html = new StringBuilder()
    .append("<div class=\"card\">")
    .append("<h2>").append("Product Title").append("</h2>")
    .append("<p>Price: $").append(String.format("%.2f", 29.99)).append("</p>")
    .append("<button>Add to Cart</button>")
    .append("</div>");

System.out.println(html.toString());

Pojemność początkowa

Należy ustawić początkową pojemność StringBuilder na przewidywaną wartość, aby uniknąć zmiany rozmiaru wewnętrznej tablicy i poprawić wydajność w przypadku dużych łańcuchów znaków.

// Default capacity: 16 chars
StringBuilder small = new StringBuilder();

// Pre-sized: 10 items * ~50 chars each
StringBuilder report = new StringBuilder(500);

for (int i = 1; i <= 10; i++) {
    report.append(String.format("%-3d. Record %04d: processed OK%n", i, i));
}

System.out.println(report.toString().substring(0, 30));
// "  1. Record 0001: processed OK"

deleteCharAt i usuwanie określonych fragmentów

deleteCharAt usuwa pojedynczy znak. delete(start, end) usuwa zakres znaków. Operacje te mają złożoność O(n) z powodu przesuwania elementów tablicy.

StringBuilder sb = new StringBuilder("Hello, World!");

sb.deleteCharAt(5);     // removes comma: "Hello World!"
sb.delete(5, 6);         // removes space: "HelloWorld!"

System.out.println(sb); // HelloWorld!

// Replace to fix a typo
StringBuilder typo = new StringBuilder("Helo, Java!");
typo.replace(typo.indexOf("Helo"), typo.indexOf("Helo") + 4, "Hello");
System.out.println(typo); // Hello, Java!

Budowanie CSV

Praktyczny wzorzec: budowanie wiersza CSV za pomocą StringBuilder z prawidłową obsługą separatorów.

import java.util.List;

static String toCsv(List<String> values) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < values.size(); i++) {
        if (i > 0) sb.append(',');
        sb.append(escapeCsv(values.get(i)));
    }
    return sb.toString();
}

static String escapeCsv(String s) {
    if (s.contains(",") || s.contains("\""))
        return "\"" + s.replace("\"", "\"\"") + "\"";
    return s;
}

System.out.println(toCsv(List.of("Alice", "Smith, Jr.", "30")));
// Alice,"Smith, Jr.",30

StringJoiner dla danych rozdzielanych separatorem

StringJoiner upraszcza łączenie elementów za pomocą separatora oraz opcjonalnego prefiksu i sufiksu — nie trzeba ręcznie obsługiwać separatorów.

import java.util.StringJoiner;

StringJoiner sj = new StringJoiner(", ", "[", "]");
sj.add("Alice");
sj.add("Bob");
sj.add("Charlie");
System.out.println(sj.toString()); // [Alice, Bob, Charlie]

// Equivalent with String.join
String joined = String.join(", ", "Alice", "Bob", "Charlie");
System.out.println(joined); // Alice, Bob, Charlie

// Streams: collect with joining collector
import java.util.stream.*;
List.of("a", "b", "c").stream()
    .collect(Collectors.joining(", ", "(", ")"));
// (a, b, c)

StringBuilder a StringBuffer

StringBuffer to bezpieczna wątkowo, synchronizowana wersja StringBuilder. Jest wolniejsza z powodu blokad. W kontekście jednowątkowym należy używać StringBuilder (w 99% przypadków).

// StringBuffer: thread-safe but slower (synchronized methods)
StringBuffer buf = new StringBuffer();
buf.append("Thread-safe");
buf.append(" but slow");

// StringBuilder: not thread-safe but faster
StringBuilder sb = new StringBuilder();
sb.append("Fast");
sb.append(" single-threaded");

// When to use StringBuffer:
// - Multiple threads write to the same buffer
// - Almost always a design smell — redesign to avoid sharing

Odwracanie i sprawdzanie palindromu

Wbudowana metoda reverse() klasy StringBuilder pozwala elegancko sprawdzać, czy tekst jest palindromem.

static boolean isPalindrome(String s) {
    String cleaned = s.toLowerCase()
        .replaceAll("[^a-z0-9]", ""); // remove non-alphanumeric
    String reversed = new StringBuilder(cleaned).reverse().toString();
    return cleaned.equals(reversed);
}

System.out.println(isPalindrome("A man, a plan, a canal: Panama")); // true
System.out.println(isPalindrome("race a car"));                      // false
System.out.println(isPalindrome("Was it a car or a cat I saw?"));    // true

Praktyczny przykład: konstruktor zapytań SQL

Budowanie dynamicznego zapytania SQL za pomocą StringBuilder, do którego klauzule where są dodawane warunkowo.

static String buildQuery(String category, Double minPrice, Double maxPrice) {
    StringBuilder sql = new StringBuilder("SELECT * FROM products WHERE 1=1");
    if (category != null)
        sql.append(" AND category = '" + category + "'");
    if (minPrice != null)
        sql.append(" AND price >= ").append(minPrice);
    if (maxPrice != null)
        sql.append(" AND price <= ").append(maxPrice);
    sql.append(" ORDER BY name");
    return sql.toString();
}

System.out.println(buildQuery("Electronics", 50.0, null));
// SELECT * FROM products WHERE 1=1 AND category = 'Electronics' AND price >= 50.0 ORDER BY name

Szybkie sprawdzenie

Dlaczego konkatenacja łańcuchów znaków za pomocą + jest nieefektywna w pętlach?

Podsumowanie: StringBuilder do wydajnej konkatenacji

Najważniejsze informacje:

  • StringBuilder jest mutowalny — append, insert i delete modyfikują wewnętrzny bufor
  • W pętlach należy używać StringBuilder, aby uniknąć tworzenia łańcuchów znaków o złożoności O(n²)
  • Wszystkie metody mutujące zwracają this, co umożliwia płynne łączenie wywołań
  • Należy ustawić StringBuilder na przewidywaną pojemność, aby ograniczyć zmiany rozmiaru wewnętrznej tablicy
  • StringJoiner i String.join ułatwiają tworzenie danych rozdzielanych separatorem
  • StringBuffer to synchronizowana (bezpieczna wątkowo), ale wolniejsza alternatywa
Bezpłatny start

Ucz się Java dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
104
Lekcje
374

Często zadawane pytania

Czy lekcja „StringBuilder do wydajnego łączenia” jest bezpłatna?

Tak — pełny tekst „StringBuilder do wydajnego łączenia” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Java Academy, przejdź na CoddyKit PRO. Kurs Java Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „StringBuilder do wydajnego łączenia”?

Używaj StringBuilder do wydajnego tworzenia łańcuchów znaków wewnątrz pętli i przy złożonym formatowaniu. Ćwiczysz Java Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Java Academy?

Nie wymagamy żadnego doświadczenia. Java Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „StringBuilder do wydajnego łączenia”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Java Academy?

Tak. Każda lekcja Java Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Niezmienność String i pula stringów
  2. StringBuilder do wydajnego łączenia
  3. Bloki tekstowe i String.format
  4. Wyrażenia regularne z Pattern i Matcher
← Powrót do Java Academy