Diferença de mutabilidade:
String
é imutável , se você tentar alterar seus valores, um outro objeto é criado, enquanto StringBuffer
e StringBuilder
são mutáveis assim que podem mudar seus valores.
Diferença de segurança da linha:
A diferença entre StringBuffer
e StringBuilder
é que StringBuffer
é seguro para threads. Portanto, quando o aplicativo precisar ser executado apenas em um único encadeamento, é melhor usá-lo StringBuilder
. StringBuilder
é mais eficiente que StringBuffer
.
Situações:
- Se sua string não for alterada, use uma classe String porque um
String
objeto é imutável.
- Se sua string puder mudar (exemplo: muita lógica e operações na construção da string) e somente será acessada a partir de um único encadeamento, o uso de a
StringBuilder
é bom o suficiente.
- Se sua string puder mudar e será acessada a partir de vários threads, use a
StringBuffer
porque StringBuffer
é síncrona para que você tenha segurança de thread.
Strings
quando alteramos o valor, outro objeto é criado. A referência de objeto antigo é anulada para que possa ser coletada pelo lixoGC
ou até mesmo coletada?String
comStringBuilder
?String
quando uma estrutura imutável é apropriada; obter uma nova sequência de caracteres de aString
pode levar a uma penalidade de desempenho inaceitável, seja no tempo ou na memória da CPU (a obtenção de substrings é eficiente na CPU porque os dados não são copiados, mas isso significa que uma quantidade potencialmente muito maior de dados pode permanecer alocada).StringBuilder
quando precisa criar uma sequência de caracteres mutável, geralmente para concatenar várias seqüências de caracteres juntas.StringBuffer
nas mesmas circunstâncias que usariaStringBuilder
, mas quando alterações na cadeia subjacente devem ser sincronizadas (porque vários segmentos estão lendo / modificando no buffer da cadeia).Veja um exemplo aqui .
fonte
O básico:
String
é uma classe imutável, não pode ser alterada.StringBuilder
é uma classe mutável que pode ser anexada, caracteres substituídos ou removidos e, finalmente, convertidos em aString
StringBuffer
é a versão sincronizada original deStringBuilder
Você deve preferir
StringBuilder
em todos os casos em que apenas um único thread acesse seu objeto.Os detalhes:
Observe também que
StringBuilder/Buffers
não é mágico, eles apenas usam uma matriz como um objeto de apoio e que a matriz precisa ser realocada sempre que ficar cheia. Certifique-se de criar seusStringBuilder/Buffer
objetos suficientemente grandes originalmente, onde eles não precisem ser constantemente redimensionados toda vez que forem.append()
chamados.O redimensionamento pode ficar muito degenerado. Basicamente, redimensiona a Matriz de apoio para 2 vezes seu tamanho atual sempre que precisar ser expandida. Isso pode resultar em grandes quantidades de RAM sendo alocadas e não usadas quando as
StringBuilder/Buffer
classes começam a crescer.Em Java
String x = "A" + "B";
usa umStringBuilder
nos bastidores. Portanto, para casos simples, não há benefício em declarar o seu. Mas se você estiver construindoString
objetos grandes, digamos menos que 4k, declararStringBuilder sb = StringBuilder(4096);
é muito mais eficiente que concatenação ou usar o construtor padrão, que tem apenas 16 caracteres. Se o seuString
for menor que 10k, inicialize-o com o construtor para 10k para ser seguro. Mas, se for inicializado para 10k, você escrever 1 caractere a mais que 10k, será realocado e copiado para uma matriz de 20k. Portanto, inicializar alto é melhor do que baixo.No caso de redimensionamento automático, no 17º caractere, a Matriz de backup é re-alocada e copiada para 32 caracteres; no 33º caractere, isso acontece novamente e você é re-alocado e copia a Matriz em 64 caracteres. Você pode ver como isso degenera em muitas re-alocações e cópias, o que você realmente está tentando evitar
StringBuilder/Buffer
em primeiro lugar.Isto é do código-fonte do JDK 6 para AbstractStringBuilder
Uma prática recomendada é inicializar
StringBuilder/Buffer
um pouco maior do que você pensa que precisará, se não souber de imediato qualString
será o tamanho , mas você pode adivinhar. Uma alocação de um pouco mais de memória do que você precisa será melhor do que muitas re-alocações e cópias.Lembre-se também de inicializar a
StringBuilder/Buffer
com a,String
pois isso alocará apenas o tamanho dos caracteres String + 16, que na maioria dos casos apenas iniciarão o ciclo degenerado de re-alocação e cópia que você está tentando evitar. O seguinte é direto do código-fonte do Java 6.Se por acaso você acabar com uma instância
StringBuilder/Buffer
que você não criou e não pode controlar o construtor chamado, existe uma maneira de evitar o comportamento degenerado de realocar e copiar. Ligue.ensureCapacity()
com o tamanho em que você deseja garantir que o resultadoString
será adequado.As alternativas:
Assim como uma nota, se você está fazendo realmente pesado
String
construção e manipulação, há uma alternativa muito mais orientado para o desempenho chamada Cordas .Outra alternativa é criar uma
StringList
implementação subclassificandoArrayList<String>
e adicionando contadores para rastrear o número de caracteres em todas as.append()
operações de mutação da lista, substituindo-o.toString()
para criarStringBuilder
o tamanho exato de que você precisa, percorrendo a lista e construindo a saída, você pode até tornarStringBuilder
uma variável de instância e 'armazenar em cache' os resultados.toString()
e só precisa gerá-la novamente quando algo mudar.Também não se esqueça de
String.format()
criar saída formatada fixa, que pode ser otimizada pelo compilador à medida que a melhora.fonte
String x = "A" + "B";
realmente compilar a ser um StringBuilder? Por que não basta compilarString x = "AB";
, ele deve usar um StringBuilder apenas se os componentes não forem conhecidos no momento da compilação.Você quer dizer concatenação?
Exemplo do mundo real: você deseja criar uma nova string dentre muitas outras .
Por exemplo, para enviar uma mensagem:
Corda
StringBuilder
Ou
StringBuffer (a sintaxe é exatamente como no StringBuilder, os efeitos diferem)
Sobre
StringBuffer
vs.StringBuilder
O primeiro é sincronizado e mais tarde não.
Portanto, se você invocá-lo várias vezes em um único encadeamento (que é 90% dos casos),
StringBuilder
será executado muito mais rápido porque não parará para ver se possui o bloqueio do encadeamento.Portanto, é recomendável usar
StringBuilder
(a menos que você tenha mais de um encadeamento acessando ao mesmo tempo, o que é raro)String
a concatenação ( usando o operador + ) pode ser otimizada pelo compilador para usarStringBuilder
embaixo, portanto, não é mais necessário se preocupar, nos dias anteriores do Java, isso era algo que todo mundo diz que deve ser evitado a todo custo, porque toda concatenação criou um novo objeto String. Compiladores modernos não fazem mais isso, mas ainda é uma boa prática usarStringBuilder
no caso de você usar um compilador "antigo".editar
Apenas para quem está curioso, é isso que o compilador faz para esta classe:
javap -c StringConcatenation
As linhas numeradas de 5 a 27 são para a String denominada "literal"
As linhas numeradas de 31 a 53 são para a String denominada "construtor"
Não há diferença, exatamente o mesmo código é executado para as duas strings.
fonte
StringBuilder
concatenação de String para executar no lado direito da tarefa. Qualquer boa implementação usará um StringBuilder nos bastidores, como você diz. Além disso, seu exemplo"a" + "b"
seria compilado em um único literal,"ab"
mas se você o usasseStringBuilder
, resultaria em duas chamadas desnecessárias paraappend()
."a"+"b"
mas dizer o que era uma concatenação de String, alterei para ser explícito. O que você não diz é: por que não é uma boa prática fazê-lo? É exatamente isso que um compilador (moderno) faz. @ distorcido, eu concordo, especialmente quando você sabe qual seria o tamanho da string final (aprox).fonte
synchronised
e é por isso .Corda
O
String class
representa cadeias de caracteres. Todos os literais de cadeia de caracteres no programa Java, como"abc"
são implementados como instâncias desta classe.Objetos de string são imutáveis, uma vez criados, não podemos mudar. ( Strings são constantes )
Se uma String for criada usando o construtor ou o método, essas strings serão armazenadas na Memória de Pilha e também
SringConstantPool
. Porém, antes de salvar no pool, ele invoca ointern()
método para verificar a disponibilidade do objeto com o mesmo conteúdo no pool usando o método equals. Se a cópia de cadeia estiver disponível no pool, retornará a referência. Caso contrário, o objeto String será adicionado ao pool e retornará a referência.+
) e à conversão de outros objetos em strings. A concatenação de strings é implementada por meio da classe StringBuilder (ou StringBuffer) e seu método de acréscimo.Os literais de string são armazenados em
StringConstantPool
.StringBuilder e StringBuffer são uma sequência mutável de caracteres. Isso significa que é possível alterar o valor desses objetos. StringBuffer possui os mesmos métodos que o StringBuilder, mas cada método no StringBuffer é sincronizado, portanto, é seguro para threads.
Os dados StringBuffer e StringBuilder podem ser criados apenas usando o novo operador. Portanto, eles são armazenados na memória Heap.
Instâncias do StringBuilder não são seguras para uso por vários threads. Se essa sincronização for necessária, é recomendável que StringBuffer seja usado.
StringBuffer e StringBuilder está tendo um métodos especiais como.,
replace(int start, int end, String str)
Ereverse()
.Quando usar qual.
Se você não vai mudar o valor toda vez, é melhor usar
String Class
. Como parte de Genéricos, se você deseja ClassificarComparable<T>
ou comparar um valor, vá emString Class
.Se você for modificar o valor toda vez que for para StringBuilder, que é mais rápido que StringBuffer. Se vários threads estiverem modificando o valor, vá para StringBuffer.
fonte
Além disso,
StringBuffer
é seguro para threads, o queStringBuilder
não é.Portanto, em uma situação em tempo real, quando diferentes threads estão acessando,
StringBuilder
pode ter um resultado indeterminado.fonte
Observe que se você estiver usando o Java 5 ou mais recente, deverá usar em
StringBuilder
vez deStringBuffer
. Na documentação da API:Na prática, você quase nunca usará isso de vários threads ao mesmo tempo, portanto, a sincronização que
StringBuffer
faz é quase sempre sobrecarga desnecessária.fonte
Pessoalmente, não acho que exista nenhum uso no mundo real
StringBuffer
. Quando é que eu gostaria de me comunicar entre vários threads manipulando uma sequência de caracteres? Isso não parece útil, mas talvez eu ainda não tenha visto a luz :)fonte
A diferença entre String e as outras duas classes é que String é imutável e as outras duas são classes mutáveis.
Mas por que temos duas classes para o mesmo propósito?
A razão é que o
StringBuffer
Thread é seguro eStringBuilder
não é.StringBuilder
é uma nova classe ativadaStringBuffer Api
e foi introduzidaJDK5
e sempre é recomendada se você estiver trabalhando em um ambiente de encadeamento único, pois é muitoFaster
Para obter detalhes completos, você pode ler http://www.codingeek.com/java/stringbuilder-and-stringbuffer-a-way-to-create-mutable-strings-in-java/
fonte
Em java, String é imutável. Sendo imutável, queremos dizer que, uma vez que uma String é criada, não podemos alterar seu valor. StringBuffer é mutável. Depois que um objeto StringBuffer é criado, apenas anexamos o conteúdo ao valor do objeto em vez de criar um novo objeto. StringBuilder é semelhante ao StringBuffer, mas não é seguro para threads. Os métodos do StingBuilder não são sincronizados, mas em comparação com outras Strings, o Stringbuilder roda mais rápido. Você pode aprender a diferença entre String, StringBuilder e StringBuffer implementando-os.
fonte