Diferença entre StringBuilder e StringBuffer


1578

Qual é a principal diferença entre StringBuffere StringBuilder? Há algum problema de desempenho ao decidir sobre qualquer um deles?

Respostas:


1667

StringBufferestá sincronizado, StringBuildernão está.


239
e StringBuilder é concebida como uma gota no substituto para StringBuffer onde a sincronização não é necessária
Joel

95
e a sincronização praticamente nunca é necessária. Se alguém quiser sincronizar em um StringBuilder, eles podem simplesmente cercar todo o bloco de código com um sincronizado (sb) {} na instância
locka

23
@locka Eu diria que StringBuffer nunca é uma boa ideia (a menos que você tem uma API que requer lo) vanillajava.blogspot.de/2013/04/...
Peter Lawrey

8
O único lugar que vejo para um StringBuffer é o console, como saída e vários utilitários de log: muitos threads podem gerar conflito. Como você não deseja que duas saídas se misturem ... mas normalmente a sincronização no nível StringBuffer é muito baixa, convém sincronizar com um appender como levelm, para que a resposta locka seja a melhor e o StringBuffer seja preterido. Isso economizaria tempo de revisão de código com iniciantes.
Remi Morin

20
Bom mnemônico para aqueles que misturam esses dois - BuFFer foi a primeira, mais antiga e, portanto, implementação sincronizada. A classe Builder mais recente usa o padrão Builder e é assíncrona.
Datageek

728

StringBuilderé mais rápido do que StringBufferporque não é synchronized.

Aqui está um teste de benchmark simples:

public class Main {
    public static void main(String[] args) {
        int N = 77777777;
        long t;

        {
            StringBuffer sb = new StringBuffer();
            t = System.currentTimeMillis();
            for (int i = N; i --> 0 ;) {
                sb.append("");
            }
            System.out.println(System.currentTimeMillis() - t);
        }

        {
            StringBuilder sb = new StringBuilder();
            t = System.currentTimeMillis();
            for (int i = N; i > 0 ; i--) {
                sb.append("");
            }
            System.out.println(System.currentTimeMillis() - t);
        }
    }
}

Uma execução de teste fornece os números de 2241 msfor StringBuffervs 753 msfor StringBuilder.


10
Mudei a string literal para algo maior: "a raposa marrom rápida" e obtive resultados mais interessantes. Basicamente, eles são tão rápidos. Na verdade, fiquei sem memória, então tive que remover alguns setes. Explicação: a sincronização é otimizada por hotspot. Basicamente, você está apenas medindo o tempo necessário para fazer isso (e provavelmente mais algumas otimizações).
Jilles van Gurp

7
Você precisa se aquecer antes. Este teste é injusto com o StringBuffer. Além disso, seria bom se realmente acrescentasse algo. Na verdade, eu virei o teste, anexei uma sequência aleatória e fiz o teste oposto. Vai dizer que não se pode confiar em benchmarks simples. O oposto mostra que StringBuffer é mais rápido. 5164 para StringBuilder vs 3699 para StringBuffer hastebin.com/piwicifami.avrasm
mmm

75
Esta é a primeira vez que vejo --> 0um loop. Levei um momento para perceber o que isso significa. Isso é algo que é realmente usado na prática, em vez da ...; i > 0; i--sintaxe usual ?
Raimund Krämer

19
Isso i -->é realmente irritante em termos de sintaxe ... Eu pensei que era uma flecha a princípio por causa dos comentários sobre a arte ASCII.
Sameer Puri

14
Outros concluem com resultados diferentes: alblue.bandlem.com/2016/04/jmh-stringbuffer-stringbuilder.html . Os benchmarks realmente devem ser feitos com o JMH, não com um simples. main()Além disso, seu benchmark é injusto. Não há aquecimento.
Lukas Eder

249

Basicamente, os StringBuffermétodos são sincronizados enquanto StringBuildernão são.

As operações são "quase" iguais, mas o uso de métodos sincronizados em um único encadeamento é um exagero.

É praticamente isso.

Citação da API StringBuilder :

Esta classe [StringBuilder] fornece uma API compatível com StringBuffer, mas sem garantia de sincronização . Essa classe foi projetada para ser usada como um substituto para o StringBuffer nos locais em que o buffer da string estava sendo usado por um único encadeamento (como geralmente é o caso). Onde possível, é recomendável que essa classe seja usada preferencialmente ao StringBuffer, pois será mais rápida na maioria das implementações.

Então foi feito para substituí-lo.

O mesmo aconteceu com Vectore ArrayList.


1
Também com Hashtablee HashMap.
shmosel 17/03/17

177

Mas precisava obter a diferença clara com a ajuda de um exemplo?

StringBuffer ou StringBuilder

Basta usar, a StringBuildermenos que você esteja realmente tentando compartilhar um buffer entre os threads. StringBuilderé o irmão mais novo não sincronizado (menos sobrecarga = mais eficiente) da StringBufferclasse sincronizada original .

StringBufferveio primeiro. A Sun estava preocupada com a correção em todas as condições, por isso a sincronizaram para garantir a segurança de threads.

StringBuilderveio mais tarde. A maioria dos usos StringBufferera de thread único e pagava desnecessariamente o custo da sincronização.

Como StringBuilderé um substituto substituto para StringBuffersem a sincronização, não haveria diferenças entre nenhum exemplo.

Se você está tentando compartilhar entre threads, pode usar StringBuffer, mas considere se a sincronização de nível superior é necessária, por exemplo, talvez em vez de usar StringBuffer, você deve sincronizar os métodos que usam o StringBuilder.


14
A primeira boa resposta !! O ponto é "a menos que você está compartilhando um amortecedor entre threads"
AlexWien

1
resposta muito detalhada!
Raúl

81

Primeiro vamos ver as semelhanças : StringBuilder e StringBuffer são mutáveis. Isso significa que você pode alterar o conteúdo deles, no mesmo local.

Diferenças : StringBuffer é mutável e sincronizado também. Onde, como StringBuilder, é mutável, mas não sincronizado por padrão.

Significado de sincronizado (sincronização) : quando algo é sincronizado, vários threads podem acessar e modificá-lo sem nenhum problema ou efeito colateral. StringBuffer é sincronizado, para que você possa usá-lo com vários threads sem qualquer problema.

Qual usar quando? StringBuilder: quando você precisa de uma string, que pode ser modificável, e apenas um thread a está acessando e modificando. StringBuffer: quando você precisa de uma string, que pode ser modificável, e vários threads a acessam e modificam.

Nota : Não use StringBuffer desnecessariamente, ou seja, não use-o se apenas um segmento estiver modificando e acessando-o, pois possui muito código de bloqueio e desbloqueio para sincronização, o que consumirá desnecessariamente o tempo da CPU. Não use bloqueios, a menos que seja necessário.


2
Só quero mencionar que as chamadas de método INDIVIDUAL do StringBuffer são seguras para threads. Mas se você tiver várias linhas de código, use um bloco de código sincronizado para garantir a segurança do encadeamento, com algum bloqueio / monitor (como de costume ...). Basicamente, não basta presumir que o uso de uma biblioteca segura para threads garanta imediatamente a segurança de threads no SEU programa!
Kevin Lee

57

Em threads únicos, o StringBuffer não é significativamente mais lento que o StringBuilder , graças às otimizações da JVM. E no multithreading, você não pode usar com segurança um StringBuilder.

Aqui está o meu teste (não uma referência, apenas um teste):

public static void main(String[] args) {

    String withString ="";
    long t0 = System.currentTimeMillis();
    for (int i = 0 ; i < 100000; i++){
        withString+="some string";
    }
    System.out.println("strings:" + (System.currentTimeMillis() - t0));

    t0 = System.currentTimeMillis();
    StringBuffer buf = new StringBuffer();
    for (int i = 0 ; i < 100000; i++){
        buf.append("some string");
    }
    System.out.println("Buffers : "+(System.currentTimeMillis() - t0));

    t0 = System.currentTimeMillis();
    StringBuilder building = new StringBuilder();
    for (int i = 0 ; i < 100000; i++){
        building.append("some string");
    }
    System.out.println("Builder : "+(System.currentTimeMillis() - t0));
}

Resultados:
strings: 319740
Buffers: 23
Construtor: 7!

Portanto, os construtores são mais rápidos que os buffers e muito mais rápidos que a concatenação de strings. Agora vamos usar um Executor para vários threads:

public class StringsPerf {

    public static void main(String[] args) {

        ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        //With Buffer
        StringBuffer buffer = new StringBuffer();
        for (int i = 0 ; i < 10; i++){
            executorService.execute(new AppendableRunnable(buffer));
        }
        shutdownAndAwaitTermination(executorService);
        System.out.println(" Thread Buffer : "+ AppendableRunnable.time);

        //With Builder
        AppendableRunnable.time = 0;
        executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        StringBuilder builder = new StringBuilder();
        for (int i = 0 ; i < 10; i++){
            executorService.execute(new AppendableRunnable(builder));
        }
        shutdownAndAwaitTermination(executorService);
        System.out.println(" Thread Builder: "+ AppendableRunnable.time);

    }

   static void shutdownAndAwaitTermination(ExecutorService pool) {
        pool.shutdown(); // code reduced from Official Javadoc for Executors
        try {
            if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
                pool.shutdownNow();
                if (!pool.awaitTermination(60, TimeUnit.SECONDS))
                    System.err.println("Pool did not terminate");
            }
        } catch (Exception e) {}
    }
}

class AppendableRunnable<T extends Appendable> implements Runnable {

    static long time = 0;
    T appendable;
    public AppendableRunnable(T appendable){
        this.appendable = appendable;
    }

    @Override
    public void run(){
        long t0 = System.currentTimeMillis();
        for (int j = 0 ; j < 10000 ; j++){
            try {
                appendable.append("some string");
            } catch (IOException e) {}
        }
        time+=(System.currentTimeMillis() - t0);
    }
}

Agora, os StringBuffers levam 157 ms para 100000 anexos. Não é o mesmo teste, mas comparado aos 37 ms anteriores, você pode assumir com segurança que os anexos de StringBuffers são mais lentos com o uso de multithreading . O motivo é que o JIT / hotspot / compiler / something faz otimizações quando detecta que não necessidade de verificar bloqueios.

Mas com StringBuilder, você tem java.lang.ArrayIndexOutOfBoundsException , porque um encadeamento simultâneo tenta adicionar algo que não deveria.

A conclusão é que você não precisa perseguir StringBuffers. E onde você tem tópicos, pense no que eles estão fazendo, antes de tentar ganhar alguns nanossegundos.


5
Você esqueceu de fazer "t0 = System.currentTimeMillis ();" antes de fazer o teste StringBuilder. Portanto, a figura exibida para StringBuilder é realmente o tempo necessário para executar o teste stringbuffer AND stringbuilder. Adicione esta linha e você verá que o StringBuilder é mais rápido em DUAS VEZES.
Gena Batsyan

Observe que withString+="some string"+i+" ; ";não é equivalente aos outros dois loops e, portanto, não é uma comparação justa.
Dave Jarvis

Exato, corrigido. As seqüências de pensamento ainda são muito lentas.
Nicolas Zozol 27/05

Você pode explicar mais por que o ArrayIndexOutOfBoundsException aumento para StringBuilder
Alireza Fattahi

Você deve usar o JMH para benchmarks. Seu benchmark é realmente impreciso.
Lukas Eder

42

O StringBuilder foi introduzido no Java 1.5 para não funcionar com JVMs anteriores.

Dos Javadocs :

A classe StringBuilder fornece uma API compatível com StringBuffer, mas sem garantia de sincronização. Essa classe foi projetada para ser usada como um substituto para o StringBuffer nos locais em que o buffer da string estava sendo usado por um único encadeamento (como geralmente é o caso). Onde possível, é recomendável que essa classe seja usada preferencialmente ao StringBuffer, pois será mais rápida na maioria das implementações.


13
1.4 está em seu fim de vida útil, portanto, dificilmente parece que valha a pena se preocupar com o pré-1.5.
Tom Hawtin - defina

@ tomHawtin-tackline não necessariamente - existem produtos empresariais lá fora, na versão 1.4, que a maioria de nós usa diariamente. Também o BlackBerry java é baseado no 1.4 e isso ainda é muito atual.
Richard Le Mesurier

E CDC e CLDC não têm StringBuilder.
Jin Kwon

37

Pretty Good Question

Aqui estão as diferenças, notei:

StringBuffer: -

StringBuffer is  synchronized
StringBuffer is  thread-safe
StringBuffer is  slow (try to write a sample program and execute it, it will take more time than StringBuilder)

StringBuilder: -

 StringBuilder is not synchronized 
 StringBuilder is not thread-safe
 StringBuilder performance is better than StringBuffer.

Coisa comum :-

Ambos têm os mesmos métodos com as mesmas assinaturas. Ambos são mutáveis.


23

StringBuffer

  • Sincronizado, portanto, seguro para threads
  • Segmento seguro, portanto lento

StringBuilder

  • Introduzido em Java 5.0
  • Assíncrono, portanto, rápido e eficiente
  • O usuário precisa explicitamente sincronizá-lo, se ele quiser
  • Você pode substituí-lo StringBuffersem nenhuma outra alteração

NOTA: Apenas operações únicas são seguras para threads, várias operações não. por exemplo, se você chamar appendduas vezes, ou appende toStringnão, não é seguro.
Peter Lawrey 13/01/19

22

StringBuilder não é seguro para threads. O buffer de cadeia é. Mais informações aqui .

EDIT: Quanto ao desempenho, após o hotspot começar, o StringBuilder é o vencedor. No entanto, para pequenas iterações, a diferença de desempenho é insignificante.


21

StringBuildere StringBuffersão quase os mesmos. A diferença é que StringBufferestá sincronizado e StringBuildernão está. Embora, StringBuilderseja mais rápido que StringBuffer, a diferença de desempenho é muito pequena. StringBuilderé um substituto de SUN StringBuffer. Apenas evita a sincronização de todos os métodos públicos. Em vez disso, sua funcionalidade é a mesma.

Exemplo de bom uso:

Se o seu texto for alterado e for usado por vários threads, é melhor usá-lo StringBuffer. Se o seu texto for alterado, mas for usado por um único thread, use StringBuilder.


19

StringBuffer

StringBuffer é mutável significa que é possível alterar o valor do objeto. O objeto criado por meio de StringBuffer é armazenado no heap. StringBuffer possui os mesmos métodos que o StringBuilder, mas cada método no StringBuffer é sincronizado, ou seja, StringBuffer é seguro para threads.

por isso, não permite que dois threads acessem simultaneamente o mesmo método. Cada método pode ser acessado por um thread por vez.

Mas ser seguro para threads também tem desvantagens, pois o desempenho do StringBuffer atinge devido à propriedade segura para threads. Portanto, StringBuilder é mais rápido que o StringBuffer ao chamar os mesmos métodos de cada classe.

O valor StringBuffer pode ser alterado, significa que pode ser atribuído ao novo valor. Hoje em dia é uma pergunta de entrevista mais comum, as diferenças entre as classes acima. O buffer de string pode ser convertido em string usando o método toString ().

StringBuffer demo1 = new StringBuffer(“Hello”) ;
// The above object stored in heap and its value can be changed .

demo1=new StringBuffer(“Bye”);
// Above statement is right as it modifies the value which is allowed in the StringBuffer

StringBuilder

StringBuilder é igual ao StringBuffer, ou seja, armazena o objeto na pilha e também pode ser modificado. A principal diferença entre o StringBuffer e o StringBuilder é que o StringBuilder também não é seguro para threads. O StringBuilder é rápido, pois não é seguro para threads.

StringBuilder demo2= new StringBuilder(“Hello”);
// The above object too is stored in the heap and its value can be modified

demo2=new StringBuilder(“Bye”);
// Above statement is right as it modifies the value which is allowed in the StringBuilder

insira a descrição da imagem aqui

Recurso: String Vs StringBuffer Vs StringBuilder


StringBuilder é imutável e tipo String é mutável
Brinda Rathod

Eu não concordaria que Strings e StringBuilders são "rápidos" e StringBuffers são "muito lentos". Veja as respostas acima.
FireCubez 16/02/19

17

String é um imutável.

StringBuffer é um mutável e sincronizado.

StringBuilder também é mutável, mas não está sincronizado.


Além disso, o StringBuffer bloqueia os Threads para acessar esses dados seguros do thread e é por isso que a operação ocorre lentamente. O StringBuilder não bloqueia o thread e é executado da maneira Multi Threading, por isso é rápido. String - quando você não precisa de seqüência de concatenar esta é uma boa maneira, mas quando ele precisa usar StringBuilder -> porque corda cria cada vez new Object na pilha, mas StringBuilder voltar mesmo objeto ...
Musa

11

O javadoc explica a diferença:

Esta classe fornece uma API compatível com StringBuffer, mas sem garantia de sincronização. Essa classe foi projetada para ser usada como um substituto para o StringBuffer nos locais em que o buffer da string estava sendo usado por um único encadeamento (como geralmente é o caso). Onde possível, é recomendável que essa classe seja usada preferencialmente ao StringBuffer, pois será mais rápida na maioria das implementações.


10

StringBuilder(introduzido no Java 5) é idêntico a StringBuffer, exceto que seus métodos não são sincronizados. Isso significa que ele tem um desempenho melhor que o último, mas a desvantagem é que não é seguro para threads.

Leia o tutorial para mais detalhes.


6

Um programa simples que ilustra a diferença entre StringBuffer e StringBuilder:

/**
 * Run this program a couple of times. We see that the StringBuilder does not
 * give us reliable results because its methods are not thread-safe as compared
 * to StringBuffer.
 * 
 * For example, the single append in StringBuffer is thread-safe, i.e.
 * only one thread can call append() at any time and would finish writing
 * back to memory one at a time. In contrast, the append() in the StringBuilder 
 * class can be called concurrently by many threads, so the final size of the 
 * StringBuilder is sometimes less than expected.
 * 
 */
public class StringBufferVSStringBuilder {

    public static void main(String[] args) throws InterruptedException {

        int n = 10; 

        //*************************String Builder Test*******************************//
        StringBuilder sb = new StringBuilder();
        StringBuilderTest[] builderThreads = new StringBuilderTest[n];
        for (int i = 0; i < n; i++) {
            builderThreads[i] = new StringBuilderTest(sb);
        }
        for (int i = 0; i < n; i++) {
            builderThreads[i].start();
        }
        for (int i = 0; i < n; i++) {
            builderThreads[i].join();
        }
        System.out.println("StringBuilderTest: Expected result is 1000; got " + sb.length());

        //*************************String Buffer Test*******************************//

        StringBuffer sb2 = new StringBuffer();
        StringBufferTest[] bufferThreads = new StringBufferTest[n];
        for (int i = 0; i < n; i++) {
            bufferThreads[i] = new StringBufferTest(sb2);
        }
        for (int i = 0; i < n; i++) {
            bufferThreads[i].start();
        }
        for (int i = 0; i < n; i++) {
            bufferThreads[i].join();
        }
        System.out.println("StringBufferTest: Expected result is 1000; got " + sb2.length());

    }

}

// Every run would attempt to append 100 "A"s to the StringBuilder.
class StringBuilderTest extends Thread {

    StringBuilder sb;

    public StringBuilderTest (StringBuilder sb) {
        this.sb = sb;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            sb.append("A");
        }

    }
}


//Every run would attempt to append 100 "A"s to the StringBuffer.
class StringBufferTest extends Thread {

    StringBuffer sb2;

    public StringBufferTest (StringBuffer sb2) {
        this.sb2 = sb2;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            sb2.append("A");
        }

    }
}

4

StringBuffer é usado para armazenar seqüências de caracteres que serão alteradas (os objetos String não podem ser alterados). Expande automaticamente conforme necessário. Classes relacionadas: String, CharSequence.

O StringBuilder foi adicionado no Java 5. É idêntico em todos os aspectos ao StringBuffer, exceto pelo fato de não estar sincronizado, o que significa que se vários encadeamentos estiverem acessando-o ao mesmo tempo, poderá haver problemas. Para programas de thread único, o caso mais comum, evitando a sobrecarga da sincronização, torna o StringBuilder muito mais rápido.


4
Programas de thread único não são o caso mais comum em Java, mas StringBuildergeralmente são locais para um método, onde são visíveis para apenas um thread.
finnw

4

StringBufferestá sincronizado, mas StringBuildernão está. Como resultado, StringBuilderé mais rápido que StringBuffer.


4

StringBuffer é mutável. Pode mudar em termos de tamanho e conteúdo. StringBuffers são seguros para threads, o que significa que eles têm métodos sincronizados para controlar o acesso, para que apenas um thread possa acessar o código sincronizado de um objeto StringBuffer por vez. Portanto, os objetos StringBuffer geralmente são seguros para uso em um ambiente com vários threads em que vários threads podem estar tentando acessar o mesmo objeto StringBuffer ao mesmo tempo.

StringBuilder A classe StringBuilder é muito semelhante ao StringBuffer, exceto que seu acesso não é sincronizado para que não seja seguro para threads. Por não ser sincronizado, o desempenho do StringBuilder pode ser melhor que o StringBuffer. Portanto, se você estiver trabalhando em um ambiente de thread único, o uso de StringBuilder em vez de StringBuffer pode resultar em aumento de desempenho. Isso também se aplica a outras situações, como uma variável local StringBuilder (ou seja, uma variável dentro de um método) em que apenas um thread acessará um objeto StringBuilder.


4

StringBuffer:

  • Multi fio
  • Sincronizado
  • Lento que StringBuilder

StringBuilder

  • Single-Thread
  • Não sincronizado
  • Mais rápido do que nunca

2
Mais precisamente, String c = a + bé equivalente a String c = new StringBuilder().append(a).append(b).toString(), portanto, não é mais rápido. É só que você criar um novo para cada atribuição corda, enquanto você poderia ter apenas um ( String d = a + b; d = d + c;é String d = new StringBuilder().append(a).append(b).toString(); d = new StringBuilder().append(d).append(c).toString();ao mesmo tempo StringBuilder sb = new StringBuilder(); sb.append(a).append(b); sb.append(c); String d = sb.toString();iria salvar uma instanciação StringBuilder).
Pique

4

Construtor de String :

int one = 1;
String color = "red";
StringBuilder sb = new StringBuilder();
sb.append("One=").append(one).append(", Color=").append(color).append('\n');
System.out.print(sb);
// Prints "One=1, Colour=red" followed by an ASCII newline.

Buffer de String

StringBuffer sBuffer = new StringBuffer("test");
sBuffer.append(" String Buffer");
System.out.println(sBuffer);  

É recomendável usar o StringBuilder sempre que possível, porque é mais rápido que o StringBuffer. No entanto, se a segurança do encadeamento for necessária, a melhor opção são os objetos StringBuffer.


Se você precisar de segurança de encadeamento, a melhor opção é usar o StringBuilder, pois o StringBuffer é seguro apenas para operações individuais. Para várias operações, você precisa de bloqueio explícito.
Peter Lawrey 13/01/19

4

Melhor uso, StringBuilderpois não é sincronizado e, portanto, oferece melhor desempenho. StringBuilderé um substituto direto do antigo StringBuffer.


3
@ Mark true, mas na maioria das vezes StringBu(ff|ild)eré uma variável local usada apenas por um único thread.
gabuzo

1
@MarkMcKenna: Mesmo em um aplicativo multithread, muitas vezes é necessário usar o bloqueio externo ou fazer um trabalho extra para evitá-lo. Por exemplo, se dois threads desejarem anexar um registro contendo várias strings a um construtor de strings, eles terão que agregar os dados a serem adicionados e, em seguida, adicioná-los como uma unidade, mesmo que isso fosse mais rápido - sem problemas de encadeamento - simplesmente executar uma sequência de operações de acréscimo discreto.
22714

3

Como StringBufferé sincronizado, ele precisa de algum esforço extra, portanto, com base no desempenho, é um pouco mais lento que StringBuilder.


3

Não há diferenças básicas entre StringBuildere StringBuffer, existem apenas algumas diferenças entre eles. Nos StringBuffermétodos são sincronizados. Isso significa que por vez, apenas um segmento pode operar com eles. Se houver mais de um encadeamento, o segundo encadeamento terá que aguardar o término do primeiro e o terceiro precisará aguardar o término do primeiro e do segundo e assim por diante. Isso torna o processo muito lento e, portanto, o desempenho no caso de StringBufferé baixo.

Por outro lado, StringBuildernão está sincronizado. Isso significa que ao mesmo tempo vários threads podem operar no mesmo StringBuilderobjeto ao mesmo tempo. Isso torna o processo muito rápido e, portanto, o desempenho StringBuilderé alto.


3

A Stringé um objeto imutável, o que significa que o valor não pode ser alterado enquanto StringBufferé mutável.

O StringBufferé sincronizado, portanto, é seguro para threads, enquanto StringBuildernão é adequado para apenas instâncias de thread único.


3
só porque StringBuffer possui código sincronizado, não significa necessariamente que StringBuffer seja seguro para threads. Considere o seguinte exemplo: StringBuffer testingBuffer = "stackoverflow"; Agora o Thread-1 está tentando anexar "1" ao testingBuffer e o Thread-2 está tentando anexar "2" ao testingBuffer. Agora, mesmo que o método append () esteja sincronizado, você não pode ter certeza se o valor de testingBuffer será "stackoverflow12" ou "stackoverflow21". Na verdade, é aconselhável pela Oracle usar o construtor de string sobre o buffer de string. Espero que isso tenha ajudado :)
Biman Tripathy

2

A principal diferença é StringBufferestá sincronizado mas StringBuilderé not.If você precisa usar mais de um segmento, então StringBuffer é recommended.But, de acordo com a velocidade de execução StringBuilderé mais rápido que StringBuffer, porque não é sincronizado.


4
StringBuffer é seguro somente para threads se você executar apenas uma operação nele. Eu não recomendaria usá-lo em vários threads, porque é muito difícil de acertar.
Peter Lawrey

@PeterLawrey, o que você quer dizer? :-)
Tamad Lang

1
@ b16db0 Quero dizer que a maioria dos usos do StringBuffer não são seguros para threads, pois fazem várias chamadas para ele sem sincronização externa, tornando a classe um pouco inútil.
Peter Lawrey

@ PeterLawrey ah, é como se o StringBuffer ainda precisasse de um ambiente sincronizado.
Tamad Lang

2

Verifique as características internas do método de acréscimo sincronizado StringBuffere do método de acréscimo não sincronizado de StringBuilder.

StringBuffer :

public StringBuffer(String str) {
    super(str.length() + 16);
    append(str);
}

public synchronized StringBuffer append(Object obj) {
    super.append(String.valueOf(obj));
    return this;
}

public synchronized StringBuffer append(String str) {
    super.append(str);
    return this;
}

StringBuilder :

public StringBuilder(String str) {
    super(str.length() + 16);
    append(str);
}

public StringBuilder append(Object obj) {
    return append(String.valueOf(obj));
}

public StringBuilder append(String str) {
    super.append(str);
    return this;
}

Como o anexo é synchronized, StringBufferpossui uma sobrecarga de desempenho em comparação com o StrinbBuildercenário de multiencadeamento. Contanto que você não esteja compartilhando buffer entre vários encadeamentos, use StringBuilder, o que é rápido devido à ausência de synchronizedmétodos append.


1

Aqui está o resultado do teste de desempenho para String vs StringBuffer vs StringBuilder . Finalmente, o StringBuilder venceu o teste. Veja abaixo o código e o resultado do teste.

Código :

private static void performanceTestStringVsStringbuffereVsStringBuilder() {
// String vs StringBiffer vs StringBuilder performance Test

int loop = 100000;
long start = 0;

// String
String str = null;
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  str += i + "test";
}
System.out.println("String - " + (System.currentTimeMillis() - start) + " ms");

// String buffer
StringBuffer sbuffer = new StringBuffer();
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Buffer - " + (System.currentTimeMillis() - start) + " ms");

// String builder
start = System.currentTimeMillis();
StringBuilder sbuilder = new StringBuilder();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Builder - " + (System.currentTimeMillis() - start) + " ms");

  }

Execute Me no ideone

Resultado :

100000 iteração para adicionar um único texto

String - 37489 ms
String Buffer - 5 ms
String Builder - 4 ms

10000 iteração para adicionar um único texto

String - 389 ms
String Buffer - 1 ms
String Builder - 1 ms

1
  • StringBuffer é seguro para threads, mas StringBuilder não é seguro para threads.
  • StringBuilder é mais rápido que StringBuffer.
  • StringBuffer é sincronizado, enquanto StringBuilder não é sincronizado.

1

StringBuffer é sincronizado e seguro para threads, StringBuilder não é sincronizado e mais rápido.


Essa diferença foi dada em todas as outras respostas a esta pergunta. Você poderia destacar algo novo?
Nico Haase
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.