clase de cadena
Esta clase representa una secuencia de caracteres. Todos los literales de cadena definidos en programas, como "This is String", son instancias de la clase String. String tiene dos características fundamentales:- esta es una clase inmutable
- esta es la clase final
final
) y las instancias de la clase no se pueden modificar después de la creación ( immutable
). Esto le da a la clase String varias ventajas importantes:
-
Debido a la inmutabilidad, el código hash de una instancia de la clase String se almacena en caché. No es necesario evaluarlo cada vez porque los valores de los campos del objeto nunca cambiarán después de su creación. Esto proporciona un alto rendimiento al utilizar esta clase como clave para
HashMap
. -
La clase String se puede utilizar en un entorno multiproceso sin sincronización adicional.
-
Otra característica de la clase String es que sobrecarga el
+
operador " " en Java. Por tanto, la concatenación (adición) de cadenas es bastante sencilla:
public static void main(String[] args) {
String command = "Follow" + " " + "the" + " " + "white" + " " + "rabbit";
System.out.println(command); // Follow the white rabbit
}
En esencia, la concatenación de cadenas se realiza mediante la clase StringBuilder o StringBuffer (a discreción del compilador) y un método append
(hablaremos de estas clases un poco más adelante). Si sumamos instancias de la clase String con instancias de otras clases, estas últimas se reducirán a una representación de cadena:
public static void main(String[] args) {
Boolean b = Boolean.TRUE;
String result = "b is " + b;
System.out.println(result); //b is true
}
Esta es otra propiedad interesante de la clase String: los objetos de cualquier clase pueden convertirse en una representación de cadena utilizando el método toString()
definido en la clase Object
y heredado por todas las demás clases. A menudo, el método toString() de un objeto se llama implícitamente. Por ejemplo, cuando mostramos algo en pantalla o agregamos un String a un objeto de otra clase. La clase String tiene una característica más. Todos los literales de cadena definidos en código Java, como "asdf", se almacenan en caché en el momento de la compilación y se agregan al llamado grupo de cadenas. Si ejecutamos el siguiente código:
String a = "Wake up, Neo";
String b = "Wake up, Neo";
System.out.println(a == b);
Veremos verdadero en la consola porque las variables a
en realidad b
se referirán a la misma instancia de la clase String que se agregó al grupo de cadenas en el momento de la compilación. Es decir, no se crean diferentes instancias de la clase con el mismo valor y se ahorra memoria.
Defectos:
No es difícil adivinar que la clase String es necesaria principalmente para trabajar con cadenas. Pero en algunos casos, las características anteriores de la clase String pueden pasar de ser ventajas a desventajas. Una vez que se crean cadenas en código Java, a menudo se realizan muchas operaciones sobre ellas:- convertir cadenas a diferentes registros;
- extracción de subcadenas;
- concatenación;
- etc.
public static void main(String[] args) {
String s = " Wake up, Neo! ";
s = s.toUpperCase();
s = s.trim();
System.out.println("\"" + s + "\"");
}
A primera vista, parece que acabamos de traducir la frase "¡Despierta, Neo!" a mayúsculas, eliminó espacios adicionales de esta cadena y la envolvió entre comillas. De hecho, debido a la inmutabilidad de la clase String, como resultado de cada operación se crean nuevas instancias de cadena y las antiguas se descartan, generando una gran cantidad de basura. ¿Cómo evitar el desperdicio de memoria?
Clase StringBuffer
Para manejar la creación de basura temporal debido a modificaciones en un objeto String, puede utilizar la clase StringBuffer. Esta esmutable
una clase, es decir cambiable. Un objeto de la clase StringBuffer puede contener un conjunto específico de caracteres, cuya longitud y valor se pueden cambiar llamando a ciertos métodos. Veamos cómo funciona esta clase. Para crear un nuevo objeto, utilice uno de sus constructores, por ejemplo:
- StringBuffer() - creará un objeto vacío (sin caracteres)
- StringBuffer(String str): creará un objeto basado en la variable str (que contiene todos los caracteres de str en la misma secuencia)
StringBuffer sb = new StringBuffer();
StringBuffer sb2 = new StringBuffer("Not empty");
La concatenación de cadenas a través de StringBuffer en Java se realiza mediante append
. En general, el método append
de la clase StringBuffer está sobrecargado de tal manera que puede aceptar casi cualquier tipo de datos:
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append(new Integer(2));
sb.append("; ");
sb.append(false);
sb.append("; ");
sb.append(Arrays.asList(1,2,3));
sb.append("; ");
System.out.println(sb); // 2; false; [1, 2, 3];
}
El método append
devuelve el objeto sobre el cual fue llamado (como muchos otros métodos), lo que permite llamarlo en una "cadena". El ejemplo anterior se puede escribir así:
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append(new Integer(2))
.append("; ")
.append(false)
.append("; ")
.append(Arrays.asList(1,2,3))
.append("; ");
System.out.println(sb); // 2; false; [1, 2, 3];
}
La clase StringBuffer tiene varios métodos para trabajar con cadenas. Enumeremos los principales:
delete(int start, int end)
— elimina una subcadena de caracteres comenzando desde la posiciónstart
y terminandoend
deleteCharAt(int index)
— elimina el carácter en la posiciónindex
insert(int offset, String str)
— inserta una líneastr
en la posiciónoffset
. El métodoinsert
también está sobrecargado y puede tomar diferentes argumentos.replace(int start, int end, String str)
- reemplazará todos los caracteres de una posiciónstart
a otraend
porstr
reverse()
— invierte el orden de todos los caracteressubstring(int start, int end)
- devolverá una subcadena comenzando de una posiciónstart
a otraend
substring(int start)
- devolverá una subcadena comenzando en la posición
start
public static void main(String[] args) {
String numbers = "0123456789";
StringBuffer sb = new StringBuffer(numbers);
System.out.println(sb.substring(3)); // 3456789
System.out.println(sb.substring(4, 8)); // 4567
System.out.println(sb.replace(3, 5, "ABCDE")); // 012ABCDE56789
sb = new StringBuffer(numbers);
System.out.println(sb.reverse()); // 9876543210
sb.reverse(); // Devolver el pedido original
sb = new StringBuffer(numbers);
System.out.println(sb.delete(5, 9)); // 012349
System.out.println(sb.deleteCharAt(1)); // 02349
System.out.println(sb.insert(1, "One")); // 0One2349
}
Ventajas:
-
Como ya se mencionó, StringBuffer es una clase mutable, por lo que trabajar con él no crea la misma cantidad de basura de memoria que con String. Por lo tanto, si se realizan muchas modificaciones en las cadenas, es mejor utilizar
StringBuffer
. -
StringBuffer es una clase segura para subprocesos. Sus métodos están sincronizados y las instancias pueden ser utilizadas por varios subprocesos simultáneamente.
Defectos:
Por un lado, la seguridad de los hilos es una ventaja de la clase y, por otro lado, es una desventaja. Los métodos sincronizados son más lentos que los métodos no sincronizados. Aquí es donde entra en juego StringBuilder. Averigüemos qué tipo de clase Java es StringBuilder, qué métodos tiene y cuáles son sus características.Clase StringBuilder
StringBuilder en Java es una clase que representa una secuencia de caracteres. Es muy similar a StringBuffer en todos los aspectos excepto en la seguridad de subprocesos. StringBuilder proporciona una API similar a la de StringBuffer. Demostremos esto usando un ejemplo familiar, reemplazando la declaración de variables de StringBufer a StringBuilder:public static void main(String[] args) {
String numbers = "0123456789";
StringBuilder sb = new StringBuilder(numbers);
System.out.println(sb.substring(3)); //3456789
System.out.println(sb.substring(4, 8)); //4567
System.out.println(sb.replace(3, 5, "ABCDE")); //012ABCDE56789
sb = new StringBuilder(numbers);
System.out.println(sb.reverse()); //9876543210
sb.reverse(); // Devolver el pedido original
sb = new StringBuilder(numbers);
System.out.println(sb.delete(5, 9)); //012349
System.out.println(sb.deleteCharAt(1)); //02349
System.out.println(sb.insert(1, "One")); //0One2349
}
La única diferencia es que StringBuffer es seguro para subprocesos y todos sus métodos están sincronizados, mientras que StringBuilder no. Ésta es la única característica. StringBuilder en Java es más rápido que StringBuffer debido a la falta de sincronización de métodos. Por lo tanto, en la mayoría de los casos, excepto en un entorno multiproceso, es mejor utilizar StringBuilder para un programa Java. Resumimos todo en una tabla comparativa de las tres clases:
Cadena frente a StringBuffer frente a StringBuilder
Cadena | búfer de cadena | Constructor de cadenas | |
---|---|---|---|
Posibilidad de cambiar | Immutable (No) |
mutable (Sí) |
mutable (Sí) |
Extensibilidad | final (No) |
final (No) |
final (No) |
Seguridad del hilo | Sí, debido a la inmutabilidad. | Sí, debido a la sincronización. | No |
Cuándo usar | Cuando se trabaja con cadenas que rara vez se modificarán | Cuando se trabaja con cadenas que se modificarán con frecuencia en un entorno de subprocesos múltiples | Cuando se trabaja con cadenas que se modificarán con frecuencia en un entorno de un solo subproceso |
GO TO FULL VERSION