Diferencia de mutabilidad:
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 seguridad del hilo:
La diferencia entre StringBuffer
y StringBuilder
es que StringBuffer
es segura para subprocesos. Entonces, cuando la aplicación necesita ejecutarse solo en un solo hilo, entonces es mejor usarla StringBuilder
. StringBuilder
es más eficiente que StringBuffer
.
Situaciones
- Si su cadena no va a cambiar, use una clase de cadena porque un
String
objeto 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 solo hilo, usar a
StringBuilder
es lo suficientemente bueno.
- Si su cadena puede cambiar, y se accederá desde varios subprocesos, use un
StringBuffer
porque StringBuffer
es sincrónico para que tenga seguridad de subprocesos.
Strings
cuando modificamos el valor, se crea otro objeto. ¿La referencia de objeto anterior se anula para que pueda ser recolectada por la basuraGC
o incluso se recolecta basura?String
withStringBuilder
?String
cuando una estructura inmutable es apropiada; obtener una nueva secuencia de caracteres de aString
puede llevar a una penalización de rendimiento inaceptable, ya sea en tiempo de CPU o memoria (obtener subcadenas es eficiente de CPU porque los datos no se copian, pero esto significa que una cantidad de datos potencialmente mucho mayor puede permanecer asignada).StringBuilder
cuando necesita crear una secuencia de caracteres mutable, generalmente para concatenar varias secuencias de caracteres juntas.StringBuffer
en las mismas circunstancias que se usaríaStringBuilder
, pero cuando los cambios en la cadena subyacente se deben sincronizar (porque varios subprocesos están leyendo / modificando el búfer de cadena).Vea un ejemplo aquí .
fuente
Los basicos:
String
es una clase inmutable, no se puede cambiar.StringBuilder
es una clase mutable a la que se puede agregar, reemplazar o eliminar caracteres y, en última instancia, convertir aString
StringBuffer
es la versión original sincronizada deStringBuilder
Debería preferir
StringBuilder
en todos los casos en los que solo tiene un único hilo accediendo a su objeto.Los detalles:
También tenga en cuenta que
StringBuilder/Buffers
no son mágicos, solo usan una matriz como objeto de respaldo y que la matriz debe reasignarse cada vez que se llena. Asegúrate de crear tusStringBuilder/Buffer
objetos lo suficientemente grandes originalmente donde no tengan que volver a dimensionarse constantemente cada vez que.append()
se los llama.El cambio de tamaño puede ser muy degenerado. Básicamente cambia el tamaño de la matriz de respaldo a 2 veces su tamaño actual cada vez que necesita expandirse. Esto puede provocar que se asignen grandes cantidades de RAM y que no se usen cuando las
StringBuilder/Buffer
clases comienzan a crecer.En Java
String x = "A" + "B";
utiliza unStringBuilder
detrás de escena. Entonces, para casos simples, no hay beneficio de declarar el suyo propio. Pero si está construyendoString
objetos que son grandes, digamos menos de 4k, entonces declararStringBuilder sb = StringBuilder(4096);
es mucho más eficiente que la concatenación o usar el constructor predeterminado que tiene solo 16 caracteres. SiString
va a tener menos de 10k, inicialícelo con el constructor a 10k para estar seguro. Pero si se inicializa a 10k, entonces escribe 1 carácter más de 10k, se reasignará y copiará en una matriz de 20k. Por lo tanto, inicializar alto es mejor que bajo.En el caso de cambio de tamaño automático, en el 17º carácter, la matriz de respaldo se reasigna y se copia a 32 caracteres, en el 33º carácter esto vuelve a ocurrir y se puede reasignar y copiar la matriz en 64 caracteres. Puede ver cómo esto degenera en muchas reasignaciones y copias, que es lo que realmente está tratando de evitar usar
StringBuilder/Buffer
en primer lugar.Esto es del código fuente de JDK 6 para AbstractStringBuilder
Una mejor práctica es inicializar
StringBuilder/Buffer
un poco más de lo que crees que vas a necesitar si no sabes de inmediato qué tan grandeString
será, pero puedes adivinar. Una asignación de un poco más de memoria de la que necesita será mejor que muchas reasignaciones y copias.También tenga cuidado de inicializar a
StringBuilder/Buffer
con a,String
ya que solo asignará el tamaño de los caracteres de Cadena + 16, que en la mayoría de los casos solo comenzará el ciclo de reasignación y copia degenerado que está tratando de evitar. Lo siguiente es directamente del código fuente de Java 6.Si por casualidad terminas con una instancia de
StringBuilder/Buffer
eso que no creaste y no puedes controlar el constructor que se llama, hay una manera de evitar el comportamiento degenerado de reasignación y copia. Llame.ensureCapacity()
con el tamaño que desea para asegurarse de que su resultadoString
se ajuste.Las alternativas
Solo como una nota, si está haciendo una
String
construcción y manipulación realmente pesadas , hay una alternativa mucho más orientada al rendimiento llamada Ropes .Otra alternativa es crear una
StringList
implementación subclasificandoArrayList<String>
y agregando contadores para rastrear el número de caracteres en todas.append()
y cada una de las operaciones de mutación de la lista, luego anular.toString()
para crear unoStringBuilder
del tamaño exacto que necesita y recorrer la lista y construir en la salida, incluso puede convertir esaStringBuilder
variable en una instancia y 'almacenar en caché' los resultados.toString()
y solo tiene que volver a generarla cuando algo cambia.Tampoco se olvide de
String.format()
crear un formato de salida fijo, que el compilador puede optimizar a medida que lo mejoran.fuente
String x = "A" + "B";
Realmente se compila para ser un StringBuilder? ¿Por qué no solo compilaría?String x = "AB";
Solo debería usar un StringBuilder si los componentes no se conocen en el momento de la compilación.¿Te refieres a concatenación?
Ejemplo del mundo real: desea crear una nueva cadena a partir de muchos otros .
Por ejemplo para enviar un mensaje:
Cuerda
StringBuilder
O
StringBuffer (la sintaxis es exactamente como con StringBuilder, los efectos difieren)
Acerca de
StringBuffer
vs.StringBuilder
El primero está sincronizado y luego no.
Entonces, si lo invoca varias veces en un solo hilo (que es el 90% de los casos),
StringBuilder
se ejecutará mucho más rápido porque no se detendrá para ver si posee el bloqueo del hilo.Por lo tanto, es recomendable usarlo
StringBuilder
(a menos que, por supuesto, tenga más de un hilo accediendo al mismo tiempo, lo cual es raro)String
el compilador puede optimizar la concatenación ( usando el operador + ) para usarStringBuilder
debajo, por lo que ya no es algo de qué preocuparse, en los días antiguos de Java, esto era algo que todo el mundo dice que debe evitarse a toda costa, porque cada concatenación creó un nuevo objeto String. Los compiladores modernos ya no hacen esto, pero aún así es una buena práctica usarloStringBuilder
en caso de que use un compilador "antiguo".editar
Solo para quién tiene curiosidad, esto es lo que hace el compilador para esta clase:
javap -c StringConcatenation
Las líneas numeradas del 5 al 27 son para la cadena llamada "literal"
Las líneas numeradas del 31 al 53 son para la cadena denominada "constructor"
No hay diferencia, exactamente el mismo código se ejecuta para ambas cadenas.
fuente
StringBuilder
concatenación de cadenas para hacer en el lado derecho de la tarea. Cualquier buena implementación utilizará un StringBuilder detrás de escena como usted dice. Además, su ejemplo de"a" + "b"
se compilaría en un solo literal,"ab"
pero si lo usara,StringBuilder
se generarían dos llamadas innecesarias aappend()
."a"+"b"
pero para decir qué era una concatenación de String, lo cambio para que sea explícito. Lo que no dice 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 cadena final (aprox.).fuente
synchronised
y esa es la razón .Cuerda
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. (Las cadenas son constantes )
Si se crea una cadena utilizando el constructor o el método a continuación, se almacenarán las cadenas en memoria de pila , así como
SringConstantPool
. Pero antes de guardar en el grupo, invoca elintern()
método para verificar la disponibilidad de objetos con el mismo contenido en el grupo usando el método igual. Si String-copy está disponible en el Pool, entonces devuelve la referencia. De lo contrario, el objeto String se agrega al grupo y devuelve la referencia.+
) 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 append.Los literales de cadena se almacenan en
StringConstantPool
.StringBuilder y StringBuffer son secuencias de caracteres mutables. 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 del montón.
Las instancias de StringBuilder no son seguras para su uso por varios subprocesos. Si se requiere dicha sincronización, se recomienda utilizar StringBuffer.
StringBuffer y StringBuilder están teniendo un métodos especiales como.,
replace(int start, int end, String str)
Yreverse()
.Cuándo usar cuál.
Si no va a cambiar el valor cada vez, es mejor usarlo
String Class
. Como parte de Generics, si desea ordenarComparable<T>
o comparar valores, elijaString Class
.Si va a modificar el valor cada vez que vaya a StringBuilder, que es más rápido que StringBuffer. Si varios hilos están modificando el valor, vaya a StringBuffer.
fuente
Además,
StringBuffer
es seguro para subprocesos, queStringBuilder
no lo es.Por lo tanto, en una situación en tiempo real cuando diferentes subprocesos acceden a él,
StringBuilder
podría tener un resultado indeterminado.fuente
Tenga en cuenta que si está utilizando Java 5 o más reciente, debe usarlo en
StringBuilder
lugar deStringBuffer
. De la documentación de la API:En la práctica, casi nunca usará esto de varios subprocesos al mismo tiempo, por lo que la sincronización
StringBuffer
es casi siempre innecesaria.fuente
Personalmente, no creo que haya un uso real en el mundo
StringBuffer
. ¿Cuándo querría comunicarme entre múltiples hilos manipulando una secuencia de caracteres? Eso no suena útil en absoluto, pero tal vez aún no haya visto la luz :)fuente
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 con el mismo propósito?
La razón es que
StringBuffer
es seguro para subprocesos yStringBuilder
no lo es.StringBuilder
es una nueva claseStringBuffer Api
y se introdujoJDK5
y siempre se recomienda si está trabajando en un entorno de un solo subproceso, ya que es muchoFaster
Para obtener detalles completos, puede leer http://www.codingeek.com/java/stringbuilder-and-stringbuffer-a-way-to-create-mutable-strings-in-java/
fuente
En java, String es inmutable. Al ser inmutable, queremos decir 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 se ejecuta más rápido. Puede aprender la diferencia entre String, StringBuilder y StringBuffer implementándolos.
fuente