Por que StringBuilder quando há String?

Acabei de encontrar o StringBuilder pela primeira vez e fiquei surpreso, pois o Java já tem uma class String muito poderosa que permite append.

Por que uma segunda class String ?

Onde posso aprender mais sobre o StringBuilder ?

    String não permite acrescentar. Cada método que você invoca em um String cria um novo object e o retorna. Isso ocorre porque String é imutável – não pode alterar seu estado interno.

    Por outro lado, StringBuilder é mutável. Quando você chama append(..) ele altera a matriz char interna, em vez de criar um novo object string.

    Assim, é mais eficiente ter:

     StringBuilder sb = new StringBuilder(); for (int i = 0; i < 500; i ++) { sb.append(i); } 

    em vez de str += i , o que criaria 500 novos objects de string.

    Note que no exemplo eu uso um loop. Como helios observa nos comentários, o compilador traduz automaticamente expressões como String d = a + b + c para algo como

     String d = new StringBuilder(a).append(b).append(c).toString(); 

    Observe também que há StringBuffer além de StringBuilder . A diferença é que o primeiro tem methods sincronizados. Se você usá-lo como uma variável local, use StringBuilder . Se acontecer de ser possível acessá-lo por vários threads, use StringBuffer (isso é mais raro)

    Aqui está um exemplo concreto sobre o porquê –

     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 

    Como você pode ver, a diferença no desempenho é significativa.

    A class String é imutável, enquanto o StringBuilder é mutável.

     String s = "Hello"; s = s + "World"; 

    O código acima criará dois objects porque String é imutável

     StringBuilder sb = new StringBuilder("Hello"); sb.append("World"); 

    O código acima criará apenas um object porque o StringBuilder não é imutável.

    Lição: Sempre que houver necessidade de manipular / update / append, o String muitas vezes vai para o StringBuilder como eficiente, comparado com o String.

    StringBuilder é para, bem, construir strings. Especificamente, construí-los de uma forma muito eficaz. A class String é boa para muitas coisas, mas na verdade tem um desempenho terrível ao montar uma nova string a partir de partes de string menores porque cada nova string é uma string totalmente nova e realocada. (É imutável ) O StringBuilder mantém a mesma sequência no local e a modifica ( mutável ).

    A class StringBuilder é mutável e, ao contrário de String, permite que você modifique o conteúdo da string sem precisar criar mais objects String, o que pode ser um ganho de desempenho quando você modifica bastante uma string. Há também uma contraparte para o StringBuilder chamado StringBuffer, que também é sincronizado, sendo ideal para ambientes multithread.

    O maior problema com o String é que qualquer operação que você fizer com ele sempre retornará um novo object, digamos:

     String s1 = "something"; String s2 = "else"; String s3 = s1 + s2; // this is creating a new object. 

    Eficiência.

    Toda vez que você concatenar strings, uma nova string será criada. Por exemplo:

     String out = "a" + "b" + "c"; 

    Isso cria uma nova string temporária, copia “a” e “b” nela para resultar em “ab”. Em seguida, ele cria outra nova string temporária, copia “ab” e “c” nela para resultar em “abc”. Este resultado é então atribuído a out .

    O resultado é um algoritmo de Schlemiel the Painter de complexidade de tempo O (n²) (quadrática).

    StringBuilder , por outro lado, permite acrescentar strings no local, redimensionando a string de saída conforme necessário.

    O StringBuilder é bom quando você está lidando com strings maiores. Isso ajuda você a melhorar o desempenho.

    Aqui está um artigo que achei que foi útil.

    Uma rápida pesquisa no google poderia ter ajudado você. Agora você contratou 7 pessoas diferentes para fazer uma pesquisa no google por você. 🙂

    Para ser preciso, o StringBuilder adicionando todas as strings é O (N) enquanto adicionar String’s é O (N ^ 2). Verificando o código-fonte, isso é obtido internamente mantendo um array mutável de chars. O StringBuilder usa a técnica de duplicação de comprimento da matriz para atingir o desempenho O (N ^ 2) amortizado , ao custo de potencialmente duplicar a memory necessária. Você pode chamar trimToSize no final para resolver isso, mas normalmente objects StringBuilder são usados ​​apenas temporariamente. Você pode melhorar ainda mais o desempenho fornecendo uma boa estimativa inicial do tamanho final da string.

    Java tem String, StringBuffer e StringBuilder:

    • Corda: seu imutável

    • StringBuffer: seu mutável e ThreadSafe

    • StringBuilder: Seu mutável mas não ThreadSafe, introduzido no Java 1.5

    String por exemplo:

     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); } } } 

    }

    output: 10 Strings diferentes serão criadas em vez de apenas 1 String.

     Helloa Helloaa Helloaaa Helloaaaa Helloaaaaa Helloaaaaaa Helloaaaaaaa Helloaaaaaaaa Helloaaaaaaaaa Helloaaaaaaaaaa 

    StringBuilder eg: Apenas 1 object StringBuilder será criado.

     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); } } } 
     int wiek = (int)roznica.TotalDays; public double GetRandomNumber(double minimum, double maximum) { Random random = new Random(); return random.NextDouble() * (maximum - minimum) + minimum; } StringBuilder sb = new StringBuilder(); sb.Append(producent + " " + kolor + " " + dataWaznosci.Date + " "); sb.Append(String.Format(" {0:0.00} zł", ObliczCene())); return sb.ToString(); using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace kolos_grD { internal class CenaMinimalnaException:Exception { public CenaMinimalnaException(string exc) : base(exc) { } } } using System.Runtime.Serialization.Formatters.Binary; using System.IO; public void Zapisz(string nazwa) { BinaryFormatter bf = new BinaryFormatter(); FileStream fs = new FileStream(nazwa + ".bin", FileMode.Create); bf.Serialize(fs, this); fs.Close(); } public static Bank Odczytaj(string nazwa) { BinaryFormatter bf = new BinaryFormatter(); FileStream fs = new FileStream(nazwa + ".bin", FileMode.Open); Bank nowy = (Bank) bf.Deserialize(fs); Konto.current_numer_konta = nowy.lista_kont.Last().numer_konta; fs.Close(); return nowy; } public void Sortuj() { List pom = lista_kont.ToList(); pom.Sort(); LinkedList nowa_lista = new LinkedList(pom); lista_kont = nowa_lista; } public int CompareTo(Farba other) { return -this.ObliczCene().CompareTo(other.ObliczCene()); }