Dopiero co spotkałem StringBuilder
się po raz pierwszy i byłem zaskoczony, ponieważ Java ma już bardzo potężną String
klasę, która umożliwia dołączanie.
Dlaczego druga String
klasa?
Gdzie mogę dowiedzieć się więcej StringBuilder
?
java
string
stringbuilder
an00b
źródło
źródło
Odpowiedzi:
String
nie pozwala na dołączanie. Każda metoda wywoływana na aString
tworzy nowy obiekt i zwraca go. Dzieje się tak, ponieważString
jest niezmienna - nie może zmienić swojego stanu wewnętrznego.Z drugiej strony
StringBuilder
jest zmienny. Kiedy wywołujeszappend(..)
, zmienia wewnętrzną tablicę znaków, zamiast tworzyć nowy obiekt ciągu.Dlatego bardziej efektywne jest posiadanie:
StringBuilder sb = new StringBuilder(); for (int i = 0; i < 500; i ++) { sb.append(i); }
zamiast
str += i
, co spowodowałoby utworzenie 500 nowych obiektów łańcuchowych.Zauważ, że w przykładzie używam pętli. Jak zauważa helios w komentarzach, kompilator automatycznie tłumaczy wyrażenia takie
String d = a + b + c
jak npString d = new StringBuilder(a).append(b).append(c).toString();
Zauważ również, że istnieje
StringBuffer
dodatek doStringBuilder
. Różnica polega na tym, że ta pierwsza ma zsynchronizowane metody. Jeśli używasz go jako zmiennej lokalnej, użyjStringBuilder
. Jeśli zdarzy się, że jest możliwe, aby uzyskać do niego dostęp przez wiele wątków, użyjStringBuffer
(to rzadsze)źródło
Oto konkretny przykład, dlaczego -
int total = 50000; String s = ""; for (int i = 0; i < total; i++) { s += String.valueOf(i); } // 4828ms StringBuilder sb = new StringBuilder(); for (int i = 0; i < total; i++) { sb.append(String.valueOf(i)); } // 4ms
Jak widać różnica w wydajności jest znacząca.
źródło
s = sb.ToString();
na koniec należy uwzględnić czas na wykonanie a, więc przynajmniej zrobiłeś to samo w obu przykładach (wynik to astring
).Klasa String jest niezmienna, podczas gdy StringBuilder jest zmienna.
String s = "Hello"; s = s + "World";
Powyższy kod utworzy dwa obiekty, ponieważ ciąg znaków jest niezmienny
StringBuilder sb = new StringBuilder("Hello"); sb.append("World");
Powyższy kod utworzy tylko jeden obiekt, ponieważ StringBuilder nie jest niezmienny.
Lekcja: Ilekroć istnieje potrzeba wielokrotnego manipulowania / aktualizowania / dołączania String, przejdź do StringBuilder jako wydajnego w porównaniu do String.
źródło
StringBuilder służy do budowania ciągów. A konkretnie budowanie ich w bardzo wydajny sposób. Klasa String jest dobra do wielu rzeczy, ale w rzeczywistości ma naprawdę straszną wydajność podczas składania nowej struny z mniejszych części struny, ponieważ każda nowa struna jest całkowicie nową, ponownie przydzieloną struną. (Jest to niezmienne ) StringBuilder utrzymuje taką samą sekwencję w miejscu i modyfikuje go ( modyfikowalnych ).
źródło
Klasa StringBuilder jest zmienna iw przeciwieństwie do String, umożliwia modyfikowanie zawartości ciągu bez konieczności tworzenia większej liczby obiektów String, co może zwiększyć wydajność, gdy mocno modyfikujesz ciąg. Istnieje również odpowiednik dla StringBuilder o nazwie StringBuffer, który jest również zsynchronizowany, więc jest idealny dla środowisk wielowątkowych.
Największym problemem związanym z String jest to, że każda operacja, którą na nim wykonasz, zawsze zwróci nowy obiekt, na przykład:
String s1 = "something"; String s2 = "else"; String s3 = s1 + s2; // this is creating a new object.
źródło
StringBuilder jest dobry, gdy masz do czynienia z większymi ciągami. Pomaga poprawić wydajność.
Oto artykuł , który okazał się pomocny.
Szybkie wyszukiwanie w Google mogłoby Ci pomóc. Teraz zatrudniłeś 7 różnych osób, aby wyszukały za Ciebie w Google. :)
źródło
Mówiąc dokładniej, dodanie wszystkich ciągów StringBuilder to O (N), a dodanie String to O (N ^ 2). Sprawdzanie kodu źródłowego odbywa się wewnętrznie poprzez zachowanie zmiennej tablicy znaków. StringBuilder wykorzystuje technikę duplikacji długości tablicy, aby osiągnąć amortyzowaną wydajność O (N ^ 2), kosztem potencjalnego podwojenia wymaganej pamięci. Możesz wywołać trimToSize na końcu, aby rozwiązać ten problem, ale zwykle obiekty StringBuilder są używane tylko tymczasowo. Możesz dodatkowo poprawić wydajność, zapewniając dobre początkowe przypuszczenie ostatecznego rozmiaru ciągu.
źródło
Wydajność.
Za każdym razem, gdy łączysz ciągi, zostanie utworzony nowy ciąg. Na przykład:
String out = "a" + "b" + "c";
Tworzy to nowy, tymczasowy ciąg, kopiuje do niego „a” i „b”, dając w wyniku „ab”. Następnie tworzy kolejny nowy, tymczasowy ciąg, kopiuje do niego „ab” i „c”, dając w wyniku „abc”. Wynik ten jest następnie przypisywany do
out
.Rezultatem jest algorytm Schlemiela the Paintera o złożoności czasowej O (n²) (kwadratowej).
StringBuilder
z drugiej strony umożliwia dołączanie ciągów w miejscu, zmieniając rozmiar ciągu wyjściowego w razie potrzeby.źródło
Java ma String, StringBuffer i StringBuilder:
Ciąg: jest niezmienny
StringBuffer: jego Mutable i ThreadSafe
StringBuilder: jego Mutable, ale nie ThreadSafe, wprowadzone w Javie 1.5
Ciąg np:
public class T1 { public static void main(String[] args){ String s = "Hello"; for (int i=0;i<10;i++) { s = s+"a"; System.out.println(s); } } }
}
wyjście: zostanie utworzonych 10 różnych ciągów zamiast tylko 1 ciągu.
StringBuilder np: Zostanie utworzony tylko 1 obiekt StringBuilder.
public class T1 { public static void main(String[] args){ StringBuilder s = new StringBuilder("Hello"); for (int i=0;i<10;i++) { s.append("a"); System.out.println(s); } } }
źródło