Por favor, dime una situación en tiempo real para comparar String
, StringBuffer
y StringBuilder
?Cadena, StringBuffer y StringBuilder
Respuesta
Mutabilidad Diferencia:
String
es inmutable , si intenta alterar sus valores, otro objeto se crea, mientras que StringBuffer
y StringBuilder
son mutables para que puedan cambiar sus valores.
Diferencia de rosca con la seguridad:
La diferencia entre StringBuffer
y StringBuilder
es que StringBuffer
es seguro para subprocesos. Entonces, cuando la aplicación necesita ejecutarse solo en un solo hilo, entonces es mejor usar StringBuilder
. StringBuilder
es más eficiente que StringBuffer
.
situaciones:
- Si la cadena no va a cambiar utilizar una clase String ya que un objeto
String
es inmutable. - Si su cadena puede cambiar (ejemplo: mucha lógica y operaciones en la construcción de la cadena) y solo se accederá desde un único hilo, usar un
StringBuilder
es suficiente. - Si su cadena puede cambiar, y se accederá desde múltiples hilos, use un
StringBuffer
porqueStringBuffer
es síncrono, por lo que tiene seguridad de hilos.
¿Quiere decir, para concatenación?
Ejemplo del mundo real: Desea crear una nueva cadena a partir de muchas otras.
Por ejemplo, para enviar un mensaje:
cadena
String s = "Dear " + user.name + "<br>" +
" I saw your profile and got interested in you.<br>" +
" I'm " + user.age + "yrs. old too"
StringBuilder
String s = new StringBuilder().append.("Dear ").append(user.name).append("<br>")
.append(" I saw your profile and got interested in you.<br>")
.append(" I'm ").append(user.age).append("yrs. old too")
.toString()
O
String s = new StringBuilder(100).appe..... etc. ...
// The difference is a size of 100 will be allocated upfront as fuzzy lollipop points out.
StringBuffer (la sintaxis es exactamente igual que con StringBuilder, TH efectos e difieren)
Sobre
StringBuffer
vs StringBuilder
El primero está sincronizado y más tarde no lo es.
Por lo tanto, si se invoca varias veces en un solo hilo (que es el 90% de los casos), se ejecutará StringBuilder
mucho más rápido, ya que no se detendrá para ver si se posee el bloqueo de rosca.
lo tanto, es recomendable utilizar StringBuilder
(a menos que, por supuesto, usted tiene más de un hilo para acceder a ella, al mismo tiempo, lo cual es raro)
String
concatenación (usando el operador +) puede ser optimizado por el compilador para usar StringBuilder
debajo, por lo tanto, ya no es algo de lo que preocuparse, en los viejos tiempos de Java, esto era algo que todos deberían evitar a toda costa, porque cada concatenación creaba un nuevo objeto String. Los compiladores modernos ya no hacen esto, pero aún así es una buena práctica usar StringBuilder
en lugar de usar un compilador "viejo".
edición
Sólo por que es curioso, esto es lo que hace el compilador para esta clase:
class StringConcatenation {
int x;
String literal = "Value is" + x;
String builder = new StringBuilder().append("Value is").append(x).toString();
}
javap -c StringConcatenation
Compiled from "StringConcatenation.java"
class StringConcatenation extends java.lang.Object{
int x;
java.lang.String literal;
java.lang.String builder;
StringConcatenation();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: new #2; //class java/lang/StringBuilder
8: dup
9: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V
12: ldC#4; //String Value is
14: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: aload_0
18: getfield #6; //Field x:I
21: invokevirtual #7; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
24: invokevirtual #8; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
27: putfield #9; //Field literal:Ljava/lang/String;
30: aload_0
31: new #2; //class java/lang/StringBuilder
34: dup
35: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V
38: ldC#4; //String Value is
40: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
43: aload_0
44: getfield #6; //Field x:I
47: invokevirtual #7; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
50: invokevirtual #8; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
53: putfield #10; //Field builder:Ljava/lang/String;
56: return
}
líneas numeradas 5-27 son para la cadena llamada "literal"
Las líneas numeradas 31-53 son para la cadena denominada "constructor"
No hay diferencia, exactamente el se ejecuta el mismo código para ambas cadenas.
este es un muy mal ejemplo. Inicializar StringBuilder con "Dear" significa que el primer .append() causará una reasignación y copia. Negar por completo cualquier eficacia que intente obtener a través de la concatenación "normal". Un mejor ejemplo sería crearlo con un tamaño inicial que contendrá todo el contenido de la Cadena final. –
NO es una buena práctica usar un 'StringBuilder' para hacer una concatenación de cadenas en el lado derecho de la asignación. Cualquier buena implementación usará un StringBuilder detrás de las escenas como dices. Además, su ejemplo de '" a "+" b "' se compilará en un solo literal '" ab "' pero si utilizó 'StringBuilder' resultaría en dos llamadas innecesarias a' append() '. –
@Mark No pretendía usar '" a "+" b "' pero decir qué era una * Concatenación de cadenas * sobre que lo cambio para que sea explícito. Lo que no dices es por qué no es una buena práctica hacerlo. Eso es exactamente lo que hace un compilador moderno. @fuzzy, estoy de acuerdo, especialmente cuando sabes cuál sería el tamaño de la cuerda final (aprox). – OscarRyz
Además, StringBuffer
es seguro para subprocesos, que StringBuilder
no lo es.
Por lo tanto, en una situación en tiempo real cuando diferentes subprocesos están accediendo a él, StringBuilder
podría tener un resultado indeterminado.
- Utiliza
String
cuando una estructura inmutable es apropiada; obtener una nueva secuencia de caracteres deString
puede acarrear una penalización inaceptable del rendimiento, ya sea en tiempo de CPU o memoria (la obtención de subcadenas es eficiente en la CPU porque los datos no se copian, pero esto significa que una cantidad potencialmente mayor de datos puede permanecer asignada). - Utiliza
StringBuilder
cuando necesita crear una secuencia de caracteres mutable, generalmente para concatenar varias secuencias de caracteres juntas. - Utiliza
StringBuffer
en las mismas circunstancias que utilizaríaStringBuilder
, pero cuando los cambios en la cadena subyacente deben estar sincronizados (porque varios hilos están leyendo/modificando el búfer de cadena).
Ver un ejemplo here.
+1, respuesta concisa. – Dolph
concisa, pero incompleta, omite la razón fundamental para utilizar StringBuilder/Buffer y es para reducir o eliminar la reasignación y copia de matriz del comportamiento de concatenación de cadena normal. –
"Utiliza String cuando se trata de cadenas inmutables": no tiene sentido. Las instancias de String ARE son inmutables, por lo que tal vez el comentario debería decir "Use String cuando el uso de memoria debido a la inmutabilidad no importa". La respuesta aceptada cubre sus bases bastante bien. – fooMonster
Los fundamentos:
String
es una clase inmutable, que no se pueden cambiar. StringBuilder
es una clase mutable que puede ser anexados, caracteres reemplazados o eliminados y finalmente convertidos a un String
StringBuffer
es la versión sincronizada original de StringBuilder
Usted debe preferir StringBuilder
en todos los casos donde se tiene una única que accede hilo tu objeto
Los detalles:
También tenga en cuenta que no son StringBuilder/Buffers
magia, sólo tiene que utilizar una matriz como un objeto respaldo y que la matriz tiene que ser re-asignado, cuando cada vez que se llena. Asegúrese de crear sus objetos StringBuilder/Buffer
suficientemente grandes originalmente donde no tengan que cambiarse de tamaño constantemente cada vez que se llame al .append()
.
El cambio de tamaño puede ser muy degenerado. Básicamente, reajusta el tamaño de la matriz de respaldo a 2 veces su tamaño actual cada vez que necesita expandirse. Esto puede ocasionar que se asignen grandes cantidades de RAM y no se usen cuando las clases StringBuilder/Buffer
comienzan a crecer.
En Java String x = "A" + "B";
utiliza un StringBuilder
detrás de escena. Entonces, para casos simples, no hay beneficio de declarar el suyo. Pero si está construyendo String
objetos que son grandes, digamos menos de 4k, entonces declarar StringBuilder sb = StringBuilder(4096);
es mucho más eficiente que la concatenación o usar el default constructor que tiene solo 16 caracteres. Si su String
va a tener menos de 10k, inicialícelo con el constructor a 10k para estar seguro. Pero si se inicializa a 10k, entonces se escribe 1 carácter más de 10k, se volverá a asignar y se copiará en una matriz de 20k. Entonces, inicializar lo alto es mejor que lo bajo.
En el caso de tamaño automático, en el 17mo carácter, la matriz de respaldo se vuelve a asignar y se copia a 32 caracteres, en el 33º personaje esto vuelve a suceder y se puede reasignar y copiar la matriz en 64 caracteres . Puede ver cómo esto degenera en lotes de reasignaciones y copias que es lo que realmente está tratando de evitar con StringBuilder/Buffer
en primer lugar.
Esto es a partir del código fuente del JDK 6 para AbstractStringBuilder
void expandCapacity(int minimumCapacity) {
int newCapacity = (value.length + 1) * 2;
if (newCapacity < 0) {
newCapacity = Integer.MAX_VALUE;
} else if (minimumCapacity > newCapacity) {
newCapacity = minimumCapacity;
}
value = Arrays.copyOf(value, newCapacity);
}
Una buena práctica es inicializar el StringBuilder/Buffer
un poco más grande de lo que piensa que va a necesitar si usted no sabe lado de la derecha cuán grande será el String
, pero usted puede adivinar. Una asignación de un poco más de memoria de la que necesita va a ser mejor que muchas reasignaciones y copias.
También tenga cuidado de inicialización de un StringBuilder/Buffer
con un String
como que sólo se asigna el tamaño de la cadena + 16 caracteres, que en la mayoría de los casos se acaba de iniciar el degenerada reasignación y copia de ciclo que se está tratando de evitar. Lo siguiente es directamente del código fuente de Java 6.
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}
Si por casualidad no terminar con una instancia de StringBuilder/Buffer
que no creó y no puede controlar el constructor que se llama, no es una manera de evitar los degenerados re-asignar y copiar el comportamiento . Llame al .ensureCapacity()
con el tamaño que desea para asegurarse de que su String
resultante encajará.
las alternativas:
Así como una nota, si usted está haciendo muy pesada String
construcción y manipulación, hay una alternativa mucho más rendimiento orientada llama Ropes.
Otra alternativa, es la creación de un implemenation StringList
por sub-clasificar a ArrayList<String>
, y la adición de contadores para realizar un seguimiento del número de caracteres en cada .append()
y otra mutación operaciones de la lista, a continuación, anular .toString()
para crear un StringBuilder
del tamaño exacto necesita recorrer la lista y crear el resultado, incluso puede hacer que StringBuilder
sea una variable de instancia y 'almacenar en caché' los resultados de .toString()
y solo tiene que volver a generarlo cuando algo cambie.
Además, no se olvide de String.format()
al compilar una salida de formato fijo, que puede ser optimizada por el compilador, ya que lo hacen mejor.
¿'String x =" A "+" B ";' realmente se compila para ser un StringBuilder? ¿Por qué no compilaría simplemente 'String x =" AB ";', solo debería usar un StringBuilder si los componentes no se conocen en tiempo de compilación. –
podría optimizar las constantes de String, no recuerdo la última vez que descompilé el código de bytes, pero sí sé que si hay alguna variable allí, seguramente usará una implementación de StringBuilder. Puede descargar el código fuente JDK y descubrirlo usted mismo. "A" + "B" es un ejemplo artificial seguro. –
Me preguntaba acerca de String.format(). Nunca he visto realmente que se use en proyectos. Por lo general, es el StringBuilder. Bueno, generalmente es "A" + "B" + "C" porque las personas son flojas;) Solía usar siempre un StringBuilder, incluso si solo se concatenaban dos cadenas, porque en el futuro, tal vez se agregarían más cadenas. . Nunca utilicé String.format() principalmente porque nunca recordé el JDK que se introdujo. Veo que es JDK1.5, lo usaría a favor de las otras opciones. – jamiebarrow
Tenga en cuenta que si utiliza Java 5 o posterior, debe usar StringBuilder
en lugar de StringBuffer
. De la documentación API:
partir de la versión JDK 5, esta clase se ha complementado con una clase equivalente diseñado para su uso por un solo hilo,
StringBuilder
. La claseStringBuilder
generalmente se debe utilizar con preferencia a esta, ya que admite todas las mismas operaciones pero es más rápida, ya que no realiza ninguna sincronización.
En la práctica, es casi nunca se usan esto desde múltiples subprocesos al mismo tiempo, por lo que la sincronización que StringBuffer
hace es casi siempre una sobrecarga innecesaria.
Personalmente, no creo que haya ningún uso del mundo real para StringBuffer
. ¿Cuándo querría comunicarme entre varios hilos manipulando una secuencia de caracteres? Eso no suena nada útil, pero tal vez aún no he visto la luz :)
En java, La cadena es inmutable. Ser inmutables significa que una vez que se crea una cadena, no podemos cambiar su valor. StringBuffer es mutable. Una vez que se crea un objeto StringBuffer, simplemente agregamos el contenido al valor del objeto en lugar de crear un nuevo objeto. StringBuilder es similar a StringBuffer pero no es seguro para subprocesos. Los métodos de StingBuilder no están sincronizados, pero en comparación con otras cadenas, Stringbuilder funciona más rápido. Puede aprender la diferencia entre String, StringBuilder and StringBuffer implementándolas.
La diferencia entre String y las otras dos clases es que String es inmutable y las otras dos son clases mutables.
¿Pero por qué tenemos dos clases para el mismo propósito?
Motivo es que StringBuffer
es Thread safe y StringBuilder
no lo es. StringBuilder
es una nueva clase de StringBuffer Api
y se introdujo en JDK5
y siempre se recomienda si está trabajando en un entorno de un solo subproceso ya que es mucho Faster
Para una completa detalles se puede leer http://www.codingeek.com/java/stringbuilder-and-stringbuffer-a-way-to-create-mutable-strings-in-java/
---------------------------------------------------------------------------------- String StringBuffer StringBuilder ---------------------------------------------------------------------------------- Storage Area | Constant String Pool Heap Heap Modifiable | No (immutable) Yes(mutable) Yes(mutable) Thread Safe | Yes Yes No Performance | Fast Very slow Fast ----------------------------------------------------------------------------------
cadena
El String class
representa cadenas de caracteres. Todos los literales de cadena en el programa Java, como "abc"
se implementan como instancias de esta clase.
Los objetos de cadena son inmutables una vez que se crean, no podemos cambiarlos. (cadenas son constantes)
Si se crea una cadena usando constructor o método entonces se almacenarán esas cadenas en memoria de la pila así como
SringConstantPool
. Pero antes de guardar en el grupo, invocaintern()
método para verificar la disponibilidad de objetos con el mismo contenido en el grupo utilizando el método equals. Si String-copy está disponible en Pool, entonces devuelve la referencia. De lo contrario, el objeto String se agrega al grupo y devuelve la referencia.- El lenguaje Java proporciona soporte especial para el operador de concatenación de cadenas (
+
), y para la conversión de otros objetos a cadenas. La concatenación de cadenas se implementa a través de la clase StringBuilder (o StringBuffer) y su método de adición.
String heapSCP = new String("Yash"); heapSCP.concat("."); heapSCP = heapSCP + "M"; heapSCP = heapSCP + 777; // For Example: String Source Code public String concat(String str) { int otherLen = str.length(); if (otherLen == 0) { return this; } int len = value.length; char buf[] = Arrays.copyOf(value, len + otherLen); str.getChars(buf, len); return new String(buf, true); }
- El lenguaje Java proporciona soporte especial para el operador de concatenación de cadenas (
literales de cadena se almacenan en
StringConstantPool
.String onlyPool = "Yash";
StringBuilder y StringBuffer son secuencia mutable de caracteres. Eso significa que uno puede cambiar el valor de estos objetos. StringBuffer tiene los mismos métodos que StringBuilder, pero cada método en StringBuffer está sincronizado, por lo que es seguro para subprocesos.
Los datos de StringBuffer y StringBuilder solo se pueden crear con un nuevo operador. Por lo tanto, se almacenan en la memoria Heap.
Las instancias de StringBuilder no son seguras para el uso de varios subprocesos. Si se requiere dicha sincronización, se recomienda utilizar StringBuffer.
StringBuffer threadSafe = new StringBuffer("Yash"); threadSafe.append(".M"); threadSafe.toString(); StringBuilder nonSync = new StringBuilder("Yash"); nonSync.append(".M"); nonSync.toString();
StringBuffer y StringBuilder están teniendo un métodos especiales como.,
replace(int start, int end, String str)
yreverse()
.NOTA: StringBuffer y SringBuilder son mutables, ya que proporciona la implementación de
Appendable Interface
.
Cuando usar que uno.
Si un no van a cambiar el valor cada vez, entonces es mejor usar
String Class
. Como parte de Generics, si desea ordenarComparable<T>
o comparar valores, vaya aString Class
.//ClassCastException: java.lang.StringBuffer cannot be cast to java.lang.Comparable Set<StringBuffer> set = new TreeSet<StringBuffer>(); set.add(threadSafe); System.out.println("Set : "+ set);
Si se van a modificar el valor cada vez que la marcha de StringBuilder que es más rápido que StringBuffer. Si varios hilos están modificando el valor, vaya por StringBuffer.
- 1. StringBuilder/StringBuffer vs. "+" Operador
- 2. StringBuilder literal Groovy/StringBuffer
- 3. StringBuffer vs StringBuilder Vs StringTokenizer
- 4. Ámbito de uso de StringBuffer/StringBuilder de cadena
- 5. ¿Debo usar StringBuilder o StringBuffer para webapps?
- 6. Java: StringBuffer y concatenación
- 7. ¿Por qué StringBuffer/StringBuilder no anula iguales o hashCode?
- 8. ¿Cuándo StringBuffer/StringBuilder no es utilizado implícitamente por el compilador?
- 9. StringBuffer está obsoleto?
- 10. ¿Por qué usar StringBuilder? StringBuffer puede trabajar con múltiples hilos y un hilo?
- 11. ¿Por qué no tener StringBuilder y StringBuffer implementando una interfaz común?
- 12. comportamiento StringBuffer para NULL objetos
- 13. String.Format vs "cadena" + "cadena" o StringBuilder?
- 14. StringBuilder vs Cadena considerando reemplazar
- 15. java outOfMemoryError con stringbuilder
- 16. Cómo recortar la cadena de StringBuilder?
- 17. StringBuilder: cómo obtener la cadena final?
- 18. Java StringBuilder and Thread Safety
- 19. StringBuilder o + =
- 20. Tamaño máximo para StringBuffer
- 21. capacidad StringBuilder()
- 22. Adjuntar con StringBuilder
- 23. StringBuilder append vs +
- 24. Scala StringBuilder
- 25. LINQ para anexar a StringBuilder desde una Cadena []
- 26. clase de cadena Python como StringBuilder en C#?
- 27. Reemplazar todas las ocurrencias de una Cadena usando StringBuilder?
- 28. .NET Concatenación de cadenas (+ y + =) vs. StringBuilder
- 29. Stringbuilder en CIL (MSIL)
- 30. StringWriter o StringBuilder
Además, el uso de String para operaciones lógicas es bastante lento, y no se aconseja en absoluto, ya que la JVM convierte la cadena a StringBuffer en el bytecode. Se pierde una gran cantidad de sobrecarga convirtiendo de String a StringBuffer y luego de vuelta a String nuevamente. –
Entonces en 'Cadenas' cuando alteramos el valor se crea otro objeto. ¿La referencia de objeto anterior está anulada, por lo que puede ser basura recogida por el 'GC' o incluso se recoge basura? –
@PietervanNiekerk ¿Qué quiere decir con operaciones lógicas? – emlai