W Javie klasa String jest niemutowalna: przy każdej operacji zmiany tworzy nowy obiekt. Klasy StringBuilder i StringBuffer są mutowalne, stosuje się je do konkatenacji w pętlach i skomplikowanych przekształceniach.
Kluczowe różnice:
String: niemutowalny, bezpieczny dla wątków bez dodatkowej synchronizacji. Idealny do czytelnego, niezmiennego tekstu (np. klucze, wiadomości).StringBuilder: mutowalny, nie jest bezpieczny dla wątków, ale szybka konkatenacja. Używany tam, gdzie stringi zmieniają się wiele razy.StringBuffer: mutowalny, bezpieczny dla wątków (metody są synchronizowane), ale wolniejszy od StringBuilder.Przykład porównania prędkości:
String s = ""; for (int i = 0; i < 10000; i++) { s += i; // za każdym razem tworzy nowy String, wolno! } // Lepiej tak: StringBuilder sb = new StringBuilder(); for (int i = 0; i < 10000; i++) { sb.append(i); } String result = sb.toString();
Pułapki:
String.intern() może powodować OutOfMemoryError w PermGen/Metaspace przy dużej liczbie unikalnych stringów.Pytanie: „Czy konkatenacja stringów za pomocą operatora "+" w pętli jest efektywna?”
Odpowiedź: Nie, za każdym razem tworzy nowy obiekt String, co obciąża pamięć i GC. Dla wielu operacji lepiej używać StringBuilder lub StringBuffer (jeśli wymagana jest bezpieczeństwo wątków).
Przykład:
String s = ""; for (int i = 0; i < 1000; i++) { s += i; // BARDZO nieefektywne! } // vs StringBuilder sb = new StringBuilder(); for (int i = 0; i < 1000; i++) { sb.append(i); }
Historia
W projekcie bankowym konkatenacja stringów z użyciem operatora "+" w dużej pętli spowolniła analitykę nocną 15 razy. Problem rozwiązano, zamieniając na StringBuilder, czas wykonania skrócił się z 40 minut do 2.
Historia
Młody programista pomylił się z wątkami i używał StringBuilder w tym samym obiekcie-fasady, do którego jednocześnie odnosiło się kilka wątków. Doprowadziło to do losowych błędów i niepoprawnych wyników z powodu braku synchronizacji.
Historia
W projekcie tworzono unikalne etykiety przy użyciu String.intern(). Przy wzroście liczby użytkowników do dziesiątek milionów JVM zaczęła wywalać OutOfMemoryError: PermGen space. Zdecydowano się zrezygnować z używania intern() i przejść na inne mechanizmy cache'owania.