Tenho essa dúvida e já tentei procurar, mas acho mais sobre StringBuilder do que sobre String e StringBuffer.
Eu li na documentação e a StringBuffer “A string buffer is like a String, but can be modified”, mas isso quer dizer que uma instância de String não pode ser modificado, não seria isso?
Gostaria saber também o que é mais viável fazer para um cadastro de clientes que precisa ficar em ordem alfabética: TreeMap ou HashMap?
Utilize o StringBuffer ou o StringBuilder quando for fazer muitas operações em alguma String.
Por exemplo, se for preencher uma String dentro de um loop.
A performance é muito maior, e não são criados novos objetos quando você concatena as Strings.
A diferença entre StringBuffer e StringBuilder é que o primeiro é thread-safe, ou seja, utilize ele caso seu objeto for compartilhado entre várias threads, caso contrario utilize StringBuilder.
Ambos possuem os mesmo métodos, apenas com esse detalher do StringBuffer ter seus métodos “synchronized”, sendo assim ele é mais lento do que o StringBuilder.
Quando a questão do TreeMap ou HashMap, o TreeMap armazena na ordem natural. Mas lembre-se que mapas armazenam no esquema KV (Chave valor).
DEDEJAVA String são imutaveis. O que isso significa ?
Significa que o valor(conteudo do Objeto não pode ser modificado) como a classe String as classes Wrapper tbm são imutaveis…
Vamos a um exemplo:
String rafa = "Rafael";
rafa.concat(" Durelli");//que valor você acha que vai ter na variavel rafa.....
System.out.println(rafa);//se voce falow Rafael acertou... o que aconteceu foi que
//o Java criou um String Rafael Durelli mas o variavel de referencia rafa não "aponta" para o Objeto Rafael Durelli e sim para Rafael...
rafa = rafa.concat(" Durelli");
System.out.println(rafa);//i agora qual é o valor de rafa ? Se você falow Rafael Durelli acertou pois rafa "aponta" para o novo Objeto criado...
Agora isso não Ocorre com StringBuilder e StringBuffer…
StringBuilder rafa = new StringBuilder("Rafael");
rafa.append(" Durelli");
System.out.println(rafa.toString);//qual o valor agora... mas uma fez se você falow Rafael Durelli acertou
A diferença crucial entre StringBuider e StringBuffer é que os metodos de StringBuffer são synchronized ou seja são thread safe.
Espero ter ajudado.
As classes wrapper de tipos primitivos (que provavelmente é de quem vc está falando) são imutáveis e parte das classes wrapper de coleções (todos que começam com unmodifiable) também o são.
Alguns wrappers de coleções são mutáveis (os Collections.synchronizedQualquerCoisa).
Aproveitando que você está estudando threads para complementar:
A palavra synchronized não é sinônimo de classe thread-safe.
Um método synchronized apenas impede que duas threads acessem ao mesmo tempo o mesmo trecho de código de um objeto.
Quando uma classe tem todos os seus métodos synchronized, dizemos que a chamada aos seus métodos é atômica. Entretanto, ainda não há garantias entre métodos. Exemplo:
public void usaBuffer()
{
buffer.append("Vinicius").append("Godoy");
}
Se duas ou mais threads acessarem o método usaBuffer() ainda corremos o risco de acabar com uma string como:
ViniciusViniciusGodoyViniciusGodoyGodoy…
Isso porque, embora todos os métodos do buffer sejam thread safe, o código de usa buffer não é. O que não corremos é o risco de terminar com uma string assim:
ViViniciusnGoiciusdoy
Afinal, cada chamada a “append” vai completar totalmente antes de retornar.
Até por isso, geralmente é preferível usar o StringBuilder no lugar do StringBuffer. Normalmente, queremos fazer mais de uma concatenação num único método, e para tornar isso correto seria melhor tornar apenas usaBuffer synchronized.
Então, basicamente, é melhor usar sempre um StringBuilder em vez de String e de StringBuffer?
E sobre o synchronized… somente a classe (dentre as 3 citadas) que usa esse tipo de método (não sei como falar)?
Seria como aquela parada de região crítica e exclusão mútua, né? Que um processo (ou thread, nesse caso) não pode acessar a região crítica (do código), porque se 2 ou mais acessarem ou mesmo tempo ocorre o problema que o Vini citou. É isso? Nossa, isso é uma baita vantagem heim?? Mas… existe alguma desvantagem em usar StringBuilder?
Vini, Rafa, xjcd, Renatu… me ajudaram muito mesmo!
Só tenho mais 2 perguntas…
Dessa maneira, eu posso substituir meus objetos Strings por StringBuilder?
e @xjcd, eu estou usando sempre o <K,V> sim. O TreeMap não armazenaria na ordem alfabética também? Se eu precisasse de uma estrutura que fizesse isso automaticamente (sem chamar algum método dela), eu deveria usar Maps ou Lists? O problema de usar List é que eu acho que teria que ordenar muitas vezes, e acho que isso é muito despendioso (falando em milhares de nomes). Até mesmo que eu não sei como algum método .sort() de uma List é feito. Se for por Bubble… deuzolivre. Já, se fosse um quicksort… ou numa árvore (como falei), seria mais rápido, porque eu teria que percorrer recursivamente somente metade das árvores, não é?
Leia o link que eu passei sobre imutabilidade que você vai ver que na maior parte das vezes é melhor trabalhar com String do que com StringBuilder. Portanto, não saia substituindo nas suas classes por aí.
A única exceção mesmo é quando você for compor uma string através de várias concatenações, especialmente dentro de algum loop. Daí vc trabalha com o StringBuilder o tempo todo e só no final gera a String imutável.
Aliás, na medida do possível, tente tornar suas classes o mais imutáveis possível.
Como o Vini falow no link que ele passou o cara lá fala que um objeto imutavel é melhor a ser usado em um <K,V>. DEDEJAVA de uma lida lá é muito interessante …