1. Comparaciones

Los programadores necesitan comparar diferentes variables entre sí todo el tiempo. Pero, como ya has visto, no todo es tan sencillo.

Los números enteros son muy fáciles de comparar: solo los usas ==y listo. Para comparar números reales , tienes que comparar su diferencia (o más bien, el valor absoluto de la diferencia) con algún número muy pequeño.

Comparar cadenas es aún más difícil. Sobre todo, esto se debe a que las cadenas son objetos. Además, los programadores a menudo quieren que la comparación de cadenas sea un poco diferente según la situación.


2. Cómo se organizan las cadenas de memoria

Como ya ha visto, las cadenas se almacenan en la memoria de manera diferente a los números enteros y reales:

Cómo se organizan las cadenas de memoria

Se utilizan dos bloques de memoria para almacenar cadenas: un bloque almacena el texto en sí (su tamaño depende del tamaño del texto) mientras que el segundo bloque (4 bytes) almacena la dirección del primer bloque .

Aunque un programador experimentado diría algo como "la String strvariable almacena una referencia a un Stringobjeto.


3. Asignación de referencias a una cadena

Los beneficios de este enfoque se hacen evidentes cuando necesita asignar una variable de cadena a otra variable de cadena. Ejemplo:

String text = "This is a very important message";
String message = text;

Y esto es lo que contendrá la memoria como resultado:

Asignación de referencias a una cadena

Después de este tipo de operación de asignación, el Stringobjeto permanece donde estaba y solo su dirección (una referencia al objeto) se copia en la messagevariable.


4. Trabajar con referencias y objetos

Pero si decide convertir una cadena a mayúsculas (letras mayúsculas), la máquina Java hace todo bien: terminará con dos Stringobjetos, y las variables texty messagealmacenarán referencias, cada una a su propio objeto.

Ejemplo:

String text = "This is a very important message";
String message = text.toUpperCase();

Y esto es lo que contendrá la memoria como resultado:

Trabajar con referencias y objetos

Tenga en cuenta que el toUpperCase()método no cambia la cadena a la que se llama. En su lugar, crea una nueva cadena (nuevo objeto) y le devuelve una referencia.

¿Qué tal un ejemplo aún más interesante? Digamos que decide pasar una cadena a un Scannerobjeto (para que lea los valores de la cadena).

Ejemplo:

String text = "10 20 40 80";
Scanner console = new Scanner(text);
int a = console.nextInt();
int b = console.nextInt();

Puede obtener más información sobre cómo Scannerfunciona la clase aquí .

Así es como se almacenará todo en la memoria:

Trabajar con referencias y objetos.  Clase de escáner

En este caso, un solo Stringobjeto permanece en la memoria tal como estaba; solo las referencias a él se transmiten y almacenan en variables.


5. Comparar referencias a Stringobjetos

Y finalmente, hemos llegado a la parte divertida: la comparación de cadenas.

Hay dos operadores que puede usar para comparar variables de cadena: ==(igual) y !=(no igual). No puede usar los operadores "mayor que", "menor que" o "mayor que o igual a"; el compilador no lo permitirá.

Pero aquí hay un matiz interesante: ¿qué se almacena realmente en las variables de cadena? Así es: direcciones (referencias) a objetos. Y son estas direcciones las que se compararán:

String text = "Hi";
String message = text;
String s1 = text.toUpperCase();
String s2 = text.toUpperCase();

Esto es lo que estará en la memoria:

Comparando referencias a objetos String

Las variables messagey textse refieren a (almacenan la dirección de) el mismo objeto. Pero las variables s1y s2almacenan referencias a objetos que son muy similares pero distintos.

Y si compara estas 4 variables en el código, obtiene el siguiente resultado:

Código Salida de consola
String text = "Hi";
String message = text;
String s1 = text.toUpperCase();
String s2 = text.toUpperCase();
System.out.println(text == message);
System.out.println(text == s1);
System.out.println(s1 == s2);
true  // The addresses are equal
false // The addresses are different
false // The addresses are different