Pergunta

O que é a diferença entre Cordas e StringBuffer em Java?

Existe um tamanho máximo para Cordas?

Foi útil?

Solução

String é usado para manipular cadeias de caracteres que não podem ser alterados (somente leitura e imutável).

StringBuffer é usado para representar caracteres que podem ser modificados.

Em termos de desempenho, StringBuffer é mais rápido ao executar concatenações. Isto porque, quando você concatenar uma String, você está criando um novo objeto (internamente) a cada vez desde String é imutável.

Você também pode usar StringBuilder que é semelhante ao StringBuffer exceto que não é sincronizada. O tamanho máximo para qualquer um destes é Integer.MAX_VALUE (2 31 - 1 = 2147483647) ou o tamanho máximo de heap dividido por 2 (veja Quantos caracteres podem uma string Java tem? ). Mais informações aqui .

Outras dicas

A String é imutável, ou seja, quando ele é criado, ele nunca pode mudar.

A StringBuffer (ou seu StringBuilder não sincronizada primo) é usado quando você precisa para construir um pedaço de cordas de peça sem a sobrecarga de construção de lotes de pequenas Strings ao longo do caminho desempenho.

O comprimento máximo para ambos é Integer.MAX_VALUE, porque eles são armazenados internamente como matrizes e matrizes de Java só tem um int para seu comprimento pseudo-campo.

A melhoria de desempenho entre Strings e StringBuffers para múltiplos concatenação é bastante significativo. Se você executar o seguinte código de teste, você vai ver a diferença. No meu laptop antigo com Java 6, recebo estes resultados:

Concat with String took: 1781ms
Concat with StringBuffer took: 0ms
public class Concat
{
    public static String concatWithString()
    {
        String t = "Cat";
        for (int i=0; i<10000; i++)
        {
            t = t + "Dog";
        }
        return t;
    }
    public static String concatWithStringBuffer()
    {
        StringBuffer sb = new StringBuffer("Cat");
        for (int i=0; i<10000; i++)
        {
            sb.append("Dog");
        }
        return sb.toString();
    }
    public static void main(String[] args)
    {
        long start = System.currentTimeMillis();
        concatWithString();
        System.out.println("Concat with String took: " + (System.currentTimeMillis() - start) + "ms");
        start = System.currentTimeMillis();
        concatWithStringBuffer();
        System.out.println("Concat with StringBuffer took: " + (System.currentTimeMillis() - start) + "ms");
    }
}
String                                          StringBuffer

Immutable                                       Mutable
String s=new String("karthik");                StringBuffer sb=new StringBuffer("karthik")
s.concat("reddy");                             sb.append("reddy");
System.out.println(s);                         System.out.println(sb);
O/P:karthik                                    O/P:karthikreddy

--->once we created a String object            ---->once we created a StringBuffer object
we can't perform any changes in the existing  we can perform any changes in the existing
object.If we are trying to perform any        object.It is nothing but mutablity of 
changes with those changes a new object       of a StrongBuffer object
will be created.It is nothing but Immutability
of a String object

Use String--->If you require immutabilty
Use StringBuffer---->If you require mutable + threadsafety
Use StringBuilder--->If you require mutable + with out threadsafety

String s=new String("karthik");
--->here 2 objects will be created one is heap and the other is in stringconstantpool(scp) and s is always pointing to heap object

String s="karthik"; 
--->In this case only one object will be created in scp and s is always pointing to that object only

String é uma classe imutável. Isto significa que uma vez que você criar uma instância de uma string assim:

String str1 = "hello";

O objeto na memória não pode ser alterada. Em vez disso você terá que criar uma nova instância, copiar a antiga Cadeia e acrescentar qualquer outra coisa como neste exemplo:

String str1 = "hello";
str1 = str1 + " world!";

O que está acontecendo realmente ouvir é que não estamos atualizando o objeto str1 existente ... estamos realocando nova memória todos juntos, copiando os "Olá" de dados e anexando "mundo!" até o fim, em seguida, Configurações da referência str1 para apontar para essa nova memória. Então, ele realmente parece mais com este sob o capô:

String str1 = "hello";
String str2 = str1 + " world!";
str1 = str2;

Assim, segue-se que este processo "copiar + colar e mover coisas ao redor na memória" pode ser muito caro se feito repitively especialmente de forma recursiva.

Quando você está nessa situação de ter que fazer coisas mais e mais utilizam StringBuilder. É mutável e pode acrescentar cordas até o fim da atual porque ele está de volta por um [gama crescente] (não 100% se que é a estrutura de dados real, poderia ser uma lista).

A partir da API:

A, sequência mutável thread-safe de caracteres. Uma memória intermédia de cadeia é como uma corda, mas pode ser modificado. Em qualquer ponto no tempo que contém uma sequência particular de caracteres, mas o comprimento e o teor da sequência pode ser alterada por meio de certas chamadas de método.

A StringBuffer é usado para criar uma única seqüência de muitas cordas, por exemplo, quando você deseja anexar partes de uma seqüência em um loop.

Você deve usar um StringBuilder em vez de um StringBuffer quando você tem apenas um único fio acessando o StringBuffer, uma vez que o StringBuilder não está sincronizado e, portanto, mais rápido.

AFAIK não há nenhum limite superior para o tamanho de Cordas em Java como linguagem, mas as JVMs provavelmente tem um limite superior.

Eu encontrei resposta interesse para Cordas desempenho comparar vs StringBuffer por Reggie Hutcherso Fonte : http: // www.javaworld.com/javaworld/jw-03-2000/jw-0324-javaperf.html

Java fornece as classes StringBuffer e corda, e a classe String é usado para manipular cadeias de caracteres que não podem ser alterados. Simplificando, objetos do tipo String são somente leitura e imutável. A classe StringBuffer é usado para representar caracteres que podem ser modificados.

A diferença de desempenho significativa entre essas duas classes é que StringBuffer é mais rápido que Cordas ao executar concatenações simples. No código de manipulação de String, cadeias de caracteres são rotineiramente concatenadas. Usando a classe String, concatenations são normalmente realizado da seguinte forma:

 String str = new String ("Stanford  ");
 str += "Lost!!";

Se você fosse usar StringBuffer para executar a mesma concatenação, você precisaria de código que se parece com isso:

 StringBuffer str = new StringBuffer ("Stanford ");
 str.append("Lost!!");

Os desenvolvedores geralmente assumem que o primeiro exemplo acima é mais eficiente porque eles pensam que o segundo exemplo, que utiliza o método de acréscimo para concatenação, é mais caro do que o primeiro exemplo, que usa o operador + para concatenar dois objetos String.

O operador + parece inocente, mas o código gerado produz algumas surpresas. Usando um StringBuffer para lata concatenação no código de produção fato de que é significativamente mais rápido do que usar uma String. Para descobrir porque este é o caso, devemos examinar o bytecode gerado a partir de nossos dois exemplos. O bytecode para o exemplo usando cordas parecido com este:

0 new #7 <Class java.lang.String>
3 dup 
4 ldc #2 <String "Stanford ">
6 invokespecial #12 <Method java.lang.String(java.lang.String)>
9 astore_1
10 new #8 <Class java.lang.StringBuffer>
13 dup
14 aload_1
15 invokestatic #23 <Method java.lang.String valueOf(java.lang.Object)>
18 invokespecial #13 <Method java.lang.StringBuffer(java.lang.String)>
21 ldc #1 <String "Lost!!">
23 invokevirtual #15 <Method java.lang.StringBuffer append(java.lang.String)>
26 invokevirtual #22 <Method java.lang.String toString()>
29 astore_1

O bytecode em locais de 0 a 9 é executado pela primeira linha de código, a saber:

 String str = new String("Stanford ");

Então, o bytecode no local 10 a 29 é executado para a concatenação:

 str += "Lost!!";

As coisas ficam interessantes aqui. O código de bytes gerado para a concatenação cria um objecto StringBuf, em seguida, chama o método de acréscimo: o objeto StringBuf temporário é criado na posição 10, e o seu método de acréscimo é chamado na posição 23. Uma vez que a classe de cadeia é imutável, um StringBuf deve ser utilizado para concatenação.

Após a concatenação é realizada no objeto StringBuffer, ele deve estar de volta convertido em uma String. Isto é feito com a chamada para o método toString na posição 26. Este método cria um novo objeto String do objeto StringBuffer temporária. A criação deste objeto StringBuffer temporária e sua posterior conversão em volta um objeto String são muito caros.

Em resumo, as duas linhas de código acima resultará na criação de três objetos:

  1. objeto Uma Corda no local 0
  2. Um objeto StringBuffer na posição 10
  3. Um objeto da corda na posição 26

Agora, vamos olhar para o bytecode gerado para o exemplo usando StringBuffer:

0 new #8 <Class java.lang.StringBuffer>
3 dup
4 ldc #2 <String "Stanford ">
6 invokespecial #13 <Method java.lang.StringBuffer(java.lang.String)>
9 astore_1
10 aload_1 
11 ldc #1 <String "Lost!!">
13 invokevirtual #15 <Method java.lang.StringBuffer append(java.lang.String)>
16 pop

O bytecode em locais 0-9 é executado para a primeira linha de código:

 StringBuffer str = new StringBuffer("Stanford ");

O bytecode no local 10 a 16 é então executado para a concatenação:

 str.append("Lost!!");

Note que, como é o caso no primeiro exemplo, o código chama o método de acréscimo de um objecto StringBuf. Ao contrário do primeiro exemplo, no entanto, não há nenhuma necessidade de criar um StringBuf temporária e, em seguida, convertê-lo em um objeto da cadeia. Este código cria somente um objeto, o StringBuffer, na posição 0.

Em conclusão, StringBuffer concatenação é significativamente mais rápido que concatenação de String. Obviamente, StringBuffers deve ser usado neste tipo de operação, quando possível. Se a funcionalidade da classe String é desejado, considere usar um StringBuffer para concatenação e, em seguida, realizar uma conversão para String.

Ao imprimir o código hash do objeto String / StringBuffer depois de qualquer operação de acréscimo também provar, String objeto está sendo recriado internamente cada vez com novos valores ao invés de usar o mesmo objeto String.

public class MutableImmutable {

/**
 * @param args
 */
public static void main(String[] args) {
    System.out.println("String is immutable");
    String s = "test";
    System.out.println(s+"::"+s.hashCode());
    for (int i = 0; i < 10; i++) {
        s += "tre";
        System.out.println(s+"::"+s.hashCode());
    }

    System.out.println("String Buffer is mutable");

    StringBuffer strBuf = new StringBuffer("test");
    System.out.println(strBuf+"::"+strBuf.hashCode());
    for (int i = 0; i < 10; i++) {
        strBuf.append("tre");
        System.out.println(strBuf+"::"+strBuf.hashCode());
    }

 }

}

Saída: Ela imprime valor do objeto juntamente com o seu código hash

    String is immutable
    test::3556498
    testtre::-1422435371
    testtretre::-1624680014
    testtretretre::-855723339
    testtretretretre::2071992018
    testtretretretretre::-555654763
    testtretretretretretre::-706970638
    testtretretretretretretre::1157458037
    testtretretretretretretretre::1835043090
    testtretretretretretretretretre::1425065813
    testtretretretretretretretretretre::-1615970766
    String Buffer is mutable
    test::28117098
    testtre::28117098
    testtretre::28117098
    testtretretre::28117098
    testtretretretre::28117098
    testtretretretretre::28117098
    testtretretretretretre::28117098
    testtretretretretretretre::28117098
    testtretretretretretretretre::28117098
    testtretretretretretretretretre::28117098
    testtretretretretretretretretretre::28117098

A StringBuffer ou seu irmão mais novo e mais rápido StringBuilder é preferida sempre que você vai fazer um monte de concatenations corda no sabor de

string += newString;

ou equivalentemente

string = string + newString;

porque as construções acima cria implicitamente new toda corda que será um grande desempenho e queda. A StringBuffer / StringBuilder está sob os capuzes melhores para ser comparado com um List<Character> dinamicamente expansível.

A String é um array de caracteres imutável.

A StringBuffer é um array de caracteres mutável. de volta muitas vezes convertido para String quando feito mutante.

Uma vez que ambos são uma matriz, o tamanho máximo de ambos é igual ao tamanho máximo de um número inteiro, o qual é 2 ^ 31-1 (ver JavaDoc , também verificar o JavaDoc para ambos String e StringBuffer) .Esta é porque o argumento .length de uma matriz é um int primitivo. (Veja Arrays ).

String é imutável, o que significa que quando você executar uma operação em uma corda que você está realmente criando uma nova seqüência inteira.

StringBuffer é mutável, e você pode anexar a ele, bem como repor a sua extensão a 0.

Na prática, o compilador parece usar StringBuffer durante a concatenação de String por motivos de desempenho .

String is immutable. 

Por quê? Verifique aqui .

StringBuffer is not. It is thread safe. 

Outras perguntas como quando usar cada e outros conceitos pode ser descoberto seguinte este .

Espero que isso ajude.

Embora eu entenda que este não é um grande fator de diferenciação, notei hoje que StringBuffer (e StringBuilder) fornece alguns métodos interessantes que cadeia não.

  • reversa ()
  • setCharAt ()

As diferenças são

  1. Apenas em string class + operador está sobrecarregado. Podemos concat dois objeto String usando + operador, mas no caso de StringBuffer não podemos.
  2. string classe é substituir toString (), equals (), hashCode () de objeto classe, mas StringBuffer apenas substituições toString ().

    String s1 = new String("abc");
    String s2 = new String("abc");
    System.out.println(s1.equals(s2));  // output true
    
    StringBuffer sb1 = new StringBuffer("abc");
    StringBuffer sb2 = new StringBuffer("abc");
    System.out.println(sb1.equals(sb2));  // output false
    
  3. string classe é tanto Serializable , bem como Comparable , mas StringBuffer é só Serializable .

    Set<StringBuffer> set = new TreeSet<StringBuffer>();
    set.add(sb1);
    set.add(sb2);
    System.out.println(set);  // gives ClassCastException because there is no Comparison mechanism
    
  4. Podemos criar um objeto String com e sem new operador, mas StringBuffer objeto só pode ser criado usando new operador.

  5. String é imutável, mas StringBuffer é mutável.
  6. StringBuffer é sincronizado, enquanto cadeia não é.
  7. StringBuf está a ter um embutido reversa () método, mas Cadeia dose não tem.

Em termos de desempenho StringBuffer é muito melhor do que String; porque sempre que você aplicar concatenação no objeto String então novo objeto String são criados em cada concatenação.

Regra Principal: Cordas são imutáveis ??(não modificável) e StringBuffer são mutáveis ??(modificável)

Aqui está o experimento programático onde você começa a diferença de desempenho

public class Test {

  public static int LOOP_ITERATION= 100000;

  public static void stringTest(){
    long startTime = System.currentTimeMillis();
    String string = "This";
    for(int i=0;i<LOOP_ITERATION;i++){
        string = string+"Yasir";
    }

    long endTime = System.currentTimeMillis();
    System.out.println(endTime - startTime);    
  }

  public static void stringBufferTest(){
    long startTime = System.currentTimeMillis();
    StringBuffer stringBuffer = new StringBuffer("This");
    for(int i=0;i<LOOP_ITERATION;i++){
        stringBuffer.append("Yasir");
    }

    long endTime = System.currentTimeMillis();
    System.out.println(endTime - startTime);
  }

  public static void main(String []args){
    stringTest()
    stringBufferTest(); 
  }
 }

Saída da corda estão em minha máquina 14800

Saída de StringBuffer estão em minha máquina 14

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top