Pregunta

¿Cuál es la diferencia entre la cadena y StringBuffer en Java?

¿Existe un tamaño máximo de cadena?

¿Fue útil?

Solución

String se utiliza para manipular cadenas de caracteres que no se pueden cambiar (de sólo lectura e inmutable).

StringBuffer se utiliza para representar los caracteres que se pueden modificar.

En cuanto al rendimiento, StringBuffer es más rápido al realizar concatenaciones. Esto se debe al concatenar una String, que está creando un nuevo objeto (internamente) cada vez desde String es inmutable.

También puede utilizar StringBuilder que es similar a StringBuffer excepto que no está sincronizado. El tamaño máximo para cualquiera de estos es Integer.MAX_VALUE (2 31 - 1 = 2147483647) o el tamaño de almacenamiento dinámico máximo dividido por 2 (ver ¿Cuántos caracteres pueden tener una cadena de Java? ). Más información aquí .

Otros consejos

A String es inmutable, es decir, cuando se la crea, nunca puede cambiar.

A StringBuffer (o su primo StringBuilder no sincronizada) se utiliza cuando se necesita para construir una pieza a pieza cadena sin la sobrecarga de rendimiento de construir un montón de pequeños Strings lo largo del camino.

La longitud máxima para ambos es Integer.MAX_VALUE, ya que se almacenan internamente como arrays, y matrices Java sólo tienen un int por su longitud pseudo-campo.

La mejora de rendimiento entre Strings y StringBuffers para la concatenación múltiple es bastante significativo. Si ejecuta el siguiente código de prueba, verá la diferencia. En mi antiguo portátil con Java 6, consigo estos 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

La cadena es una clase inmutable. Esto significa que una vez que se crea una instancia de una cadena de este modo:

String str1 = "hello";

El objeto en la memoria no puede ser alterado. En su lugar, tendrá que crear una nueva instancia, copia la cadena antigua y añadir cualquier otra cosa, como en este ejemplo:

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

Lo que realmente sucede escuchar es que no estamos actualizando el objeto str1 existente ... estamos reasignando nueva memoria todos juntos, la copia de los datos de "Hola" y añadiendo "mundo!" hasta el final, luego Configuración de la referencia str1 a punto para esta nueva memoria. Por lo que realmente se parece más a esto bajo el capó:

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

Por lo tanto se deduce que este proceso "copiar + pegar y mover cosas de un lado en la memoria" puede ser muy costoso si se hace repitively especialmente de forma recursiva.

Cuando estás en esa situación de tener que hacer las cosas una y otra utilizar StringBuilder. Es mutable y puede anexar cadenas al final de la actual porque es de nuevo por una [creciente variedad] (no 100% si esa es la estructura de datos actual, podría ser una lista).

Desde el :

  

A, secuencia mutable thread-safe de caracteres. Un búfer de cadena es como una cadena, pero puede ser modificado. En cualquier punto en el tiempo que contiene alguna secuencia particular de caracteres, pero la longitud y el contenido de la secuencia se puede cambiar a través de ciertas llamadas de método.

A StringBuffer se utiliza para crear una única cadena de muchas cadenas, por ejemplo, cuando se desea anexar partes de una cadena en un bucle.

Debe utilizar un StringBuilder en lugar de un StringBuffer cuando se tiene un solo hilo acceder al StringBuffer, ya que el StringBuilder no está sincronizada y por lo tanto más rápido.

Que yo sepa no hay límite superior para el tamaño de la cadena en Java como lenguaje, pero las JVM probable que tenga un límite superior.

He encontrado respuesta interés para comparar el rendimiento de cuerdas vs StringBuffer por Reggie Hutcherso Fuente http: // www.javaworld.com/javaworld/jw-03-2000/jw-0324-javaperf.html

Java proporciona las clases StringBuffer y String, y la clase String se utiliza para manipular cadenas de caracteres que no se pueden cambiar. En pocas palabras, los objetos de tipo String única e inmutable se leen. La clase StringBuffer se utiliza para representar los caracteres que se pueden modificar.

La diferencia de rendimiento significativa entre estas dos clases es que StringBuffer es más rápido que cuando se realiza Cadena concatenaciones simples. En el código de manipulación de cadenas, cadenas de caracteres se concatenan de manera rutinaria. Utilización de la clase String, concatenaciones se realizan típicamente como sigue:

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

Si se va a usar StringBuffer para realizar la misma concatenación, se necesitaría código que se parece a esto:

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

Desarrolladores normalmente suponen que el primer ejemplo anterior es más eficiente porque piensan que el segundo ejemplo, que utiliza el método append para la concatenación, es más costoso que el primer ejemplo, que utiliza el operador + para concatenar dos objetos String.

El operador + aparece inocente, pero genera el código produce algunas sorpresas. El uso de un StringBuffer para la concatenación de hecho, puede producir código que es significativamente más rápido que el uso de una cadena. Para descubrir por qué este es el caso, hay que examinar el código de bytes generado a partir de nuestros dos ejemplos. El código de bytes para el ejemplo utilizando cuerdas se parece a esto:

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

El código de bytes en ubicaciones 0 a 9 se ejecuta para la primera línea de código, a saber:

 String str = new String("Stanford ");

A continuación, el código de bytes en la ubicación 10 a través de 29 se ejecuta para la concatenación:

 str += "Lost!!";

Las cosas se ponen interesantes aquí. El código de bytes generada por la concatenación crea un objeto StringBuffer, a continuación, invoca su método de agregación: el objeto StringBuffer temporal se crea en la ubicación 10, y su método de agregación se llama en la dirección 23. Debido a que la clase String es inmutable, un StringBuffer debe ser utilizado para concatenación.

Después de la concatenación se realiza en el objeto StringBuffer, debe ser convertida de nuevo en una cadena. Esto se hace con la llamada al método toString en el lugar 26. Este método crea un nuevo objeto String del objeto temporal StringBuffer. La creación de este objeto temporal StringBuffer y su posterior conversión de nuevo en un objeto String son muy caros.

En resumen, las dos líneas de código anteriormente dan como resultado la creación de tres objetos:

  1. Un objeto de cadena en la posición 0
  2. objeto A StringBuffer en la ubicación 10
  3. Un objeto de cadena en la posición 26

Ahora, vamos a ver el código de bytes generada por el ejemplo el uso de 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

El código de bytes en ubicaciones 0 a 9 se ejecuta para la primera línea de código:

 StringBuffer str = new StringBuffer("Stanford ");

se ejecuta entonces el código de bytes en la ubicación 10 a 16 para la concatenación:

 str.append("Lost!!");

Observe que, como es el caso en el primer ejemplo, este código invoca el método append de un objeto StringBuffer. A diferencia del primer ejemplo, sin embargo, no hay necesidad de crear un StringBuffer temporal y luego convertirlo en un objeto String. Este código crea un solo objeto, el StringBuffer, en la posición 0.

En conclusión, StringBuffer concatenación es significativamente más rápido que la concatenación de cadenas. Obviamente, StringBuffers deben utilizarse en este tipo de operaciones cuando sea posible. Si se desea la funcionalidad de la clase String, considerar el uso de un StringBuffer para la concatenación y luego realizar una conversión a cadena.

Al imprimir el código hash de la cadena / objeto StringBuffer después de cualquier operación de anexión también demostrar, objeto cadena es conseguir recrea internamente cada vez con nuevos valores en lugar de utilizar el mismo 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());
    }

 }

}

Salida: Se imprime el valor del objeto junto con su 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 o su hermano menor y más rápido StringBuilder se prefiere cada vez que va a hacer un montón de concatenaciones de cadenas en el sabor de los

string += newString;

o equivalentemente

string = string + newString;

debido a que las construcciones anteriores crea implícitamente nueva cada cadena que será un gran rendimiento y gota. A StringBuffer / StringBuilder está bajo las capuchas mejores para ser comparado con un List<Character> dinámicamente expansible.

A String es un array de caracteres inmutables.

A StringBuffer es una matriz de caracteres mutable. A menudo se convierte de nuevo a String cuando se hace mutar.

ya que ambos son una matriz, el tamaño máximo para ambos es igual al tamaño máximo de un número entero, que es 2 ^ 31-1 (ver JavaDoc , también echa un vistazo a la JavaDoc tanto para String y StringBuffer) .Esta es porque el argumento de .length una matriz es un int primitivo. (Ver Arrays ).

La cadena es inmutable, lo que significa que cuando se realiza una operación en una cadena que está realmente creando una cadena completamente nuevo.

StringBuffer es mutable, y usted puede añadir a ella, así como restablecer su longitud a 0.

En la práctica, el compilador parece usar StringBuffer durante la concatenación de cadenas por razones de rendimiento .

String is immutable. 

¿Por qué? Compruebe aquí .

StringBuffer is not. It is thread safe. 

Otras preguntas como cuándo utilizar cuales y otros conceptos pueden ser descubierto siguiente este .

Espero que esto ayude.

Si bien entiendo que esto no es un factor diferenciador importante, me di cuenta hoy que StringBuffer (y StringBuilder) proporciona algunos métodos interesantes que cadena no.

  • inversa ()
  • setCharAt ()

Las diferencias son

  1. Sólo Cadena clases + operador está sobrecargado. Podemos concat dos objeto String utilizando + operador, pero en el caso de StringBuffer no podemos.
  2. string clase está anulando toString (), es igual a (), hashCode () de Objeto clase, pero StringBuffer sólo las anulaciones 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. cadena clase es tanto Serializable así como Comparable , pero StringBuffer sólo 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 crear un objeto String con y sin nueva operador, pero objeto StringBuffer sólo pueden crearse utilizando nueva operador.

  5. La cadena es inmutable, sino StringBuffer es mutable.
  6. StringBuffer está sincronizado, mientras que la cadena no es.
  7. StringBuffer está teniendo un incorporado inversa () método, pero Cadena dosen't tienen.

En cuanto al rendimiento StringBuffer es mucho mejor que la cadena; porque siempre que se aplica en la concatenación de cadena del objeto a continuación nuevo objeto String se crean en cada concatenación.

regla principal: String son inmutables (no modificable) y StringBuffer son mutables (modificable)

Este es el experimento programática donde se obtiene la diferencia de rendimiento

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

salida de string están en mi máquina    14800

Salida de StringBuffer están en mi máquina   14

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top