====== 02.4 - Estructuras de datos estáticas ======
===== 1. String =====
Un ''String'' representa una **cadena de caracteres** (texto). Aunque en Java es un objeto, conceptualmente se comporta como una **secuencia de caracteres inmutable** y de tamaño fijo.
// Inicialización directa (literal)
String nombre = "Ana";
// Mediante la palabra clave new (crea un objeto explícito en memoria)
String apellido = new String("García");
==== Inmutabilidad ====
Una propiedad fundamental de los ''String'' es que son **inmutables**: una vez creada la cadena en memoria, **su contenido no se puede modificar**.
Cualquier método que apliquemos sobre un ''String'' (convertir a mayúsculas, reemplazar letras, etc.) **no modifica el texto original**, sino que devuelve un **nuevo String** con la transformación.
String texto = "hola";
texto.toUpperCase(); // NO modifica la variable 'texto'
IO.println(texto); // Muestra "hola"
// Para conservar el resultado, debemos reasignarlo a la variable:
texto = texto.toUpperCase();
IO.println(texto); // Muestra "HOLA"
==== Acceso y longitud ====
A diferencia de los arrays donde usamos corchetes ''[]'' y la propiedad ''.length'', en los ''String'' utilizamos **métodos**:
* **Longitud**: ''cadena.length()'' (devuelve el número de caracteres).
* **Acceso a un carácter**: ''cadena.charAt(posición)'' (las posiciones van desde **0 hasta length() - 1**).
String mensaje = "Java";
IO.println("Longitud: " + mensaje.length()); // Muestra 4
IO.println("Primer carácter: " + mensaje.charAt(0)); // Muestra 'J'
IO.println("Último carácter: " + mensaje.charAt(mensaje.length() - 1)); // Muestra 'a'
==== Comparación de Strings ====
En Java **NUNCA** debemos usar el operador ''=='' para comparar el contenido de dos cadenas. El operador ''=='' comprueba si ambas variables apuntan a la **misma posición de memoria**, no si contienen las mismas letras.
Para comparar texto debemos usar el método **''.equals()''** o **''.equalsIgnoreCase()''** (para ignorar mayúsculas y minúsculas):
String texto1 = IO.readln("Introduce una palabra: "); // Ejemplo: "hola"
String texto2 = "hola";
// INCORRECTO: Compara referencias de memoria (daría false casi siempre)
if (texto1 == texto2) {
IO.println("Apuntan al mismo objeto en memoria");
}
// CORRECTO: Compara el contenido de las cadenas
if (texto1.equals(texto2)) {
IO.println("El texto es exactamente igual");
}
// Compara ignorando mayúsculas y minúsculas
if (texto1.equalsIgnoreCase("HOLA")) {
IO.println("Coinciden sin importar mayúsculas/minúsculas");
}
==== Métodos principales de String ====
La clase ''String'' dispone de multitud de métodos para manipular texto de forma sencilla:
^ Método ^ Descripción ^ Ejemplo ^ Resultado ^
| ''contains(texto)'' | Comprueba si contiene una subcadena | ''"Programación".contains("grama")'' | ''true'' |
| ''indexOf(texto)'' | Devuelve la posición de la primera aparición (o -1 si no existe) | ''"Java".indexOf("v")'' | ''2'' |
| ''substring(inicio, fin)'' | Extrae el texto desde ''inicio'' hasta ''fin - 1'' | ''"Elefante".substring(0, 3)'' | ''"Ele"'' |
| ''toLowerCase()'' / ''toUpperCase()'' | Convierte todo el texto a minúsculas / mayúsculas | ''"Java".toLowerCase()'' | ''"java"'' |
| ''replace(viejo, nuevo)'' | Reemplaza un texto por otro | ''"Casa".replace("a", "o")'' | ''"Coso"'' |
| ''trim()'' | Elimina espacios en blanco al inicio y al final | ''" Hola ".trim()'' | ''"Hola"'' |
==== Recorrido y conversión a char[] ====
Podemos recorrer un ''String'' carácter a carácter utilizando un bucle ''for'' con ''charAt()'', o convirtiéndolo directamente a un array de caracteres (''char[]''):
String palabra = "Algoritmo";
// Opción 1: Recorrido con bucle for tradicional y charAt()
for (int i = 0; i < palabra.length(); i++) {
char letra = palabra.charAt(i);
IO.println("Posición " + i + ": " + letra);
}
// Opción 2: Convertir a char[] y recorrer con for-each
char[] letras = palabra.toCharArray();
for (char letra : letras) {
IO.print(letra + " ");
}
IO.println("");
===== 2. Arrays =====
Los ''array'' permiten almacenar un conjunto finito de elementos del mismo tipo con un tamaño fijo asignado desde su creación.
* **Declaración**: ''tipo[] nombre'';
* **Creación (instanciación)**: ''nombre = new tipo[tamaño]'';
Las posiciones se numeran **desde la 0 hasta tamaño - 1**. Para acceder o modificar un valor usamos los corchetes ''[]''.
int[] numbers;
numbers = new int[10];
//int[] numbers = new int[10];
Para almacenar valores en cada una de las posiciones del ''array'', usamos corchetes (''[]'') indicando en su interior la posición en la que queremos leer o escribir.
numbers[3] = 10;
Para acceder a los datos de un ''array'' accedemos mediante ''nombre[posicion]''.
int number;
number = numbers[3];
==== Propiedad length y recorridos ====
La propiedad ''length'' nos devuelve el número total de elementos. Podemos recorrer el array mediante un bucle ''for'' convencional o con un bucle ''for-each'':
// Recorrido con for tradicional
for (int i = 0; i < numbers.length; i++) {
IO.println("Índice " + i + ": " + numbers[i]);
}
// Recorrido con for-each (más limpio para lectura)
for (int number : numbers) {
IO.println(number);
}
Inicializar ''array'':
int[] numbers = new int[5];
for(int i=0; i
Otra forma de inicializar un ''array'' es definiendo sus valores como una lista separada por comas encerrada entre llaves. Ésto lo debemos hacer a la hora de la declaración del ''array'', y no hace falta indicarle la longitud, ya que se lo indicamos con el número de elementos que le pasemos:
int[] numbers = {1, 3, 312, 15, 69, 7, 8, 9, 0, 1};
==== Arrays multidimensionales ====
Podemos declarar un ''array'' de más de una dimensión (como tablas o matrices):
// Inicialización directa
int[][] table = {
{3, 5, 6},
{2, 4, 9}
};
// Recorrido con bucles anidados
for (int[] row : table) {
for (int cell : row) {
IO.print(cell + " ");
}
IO.println("");
}
==== Paso de arrays a funciones ====
A diferencia de los tipos primitivos, los ''arrays'' son objetos. Al pasarlos como parámetro a un método, se copia la referencia a la memoria original. Por tanto, cualquier cambio dentro del método modificará el ''array'' original.
static void main() {
int[] numbers = {1, 2, 3};
updateFirst(numbers);
IO.println(numbers[0]); // Muestra 99
}
static void updateFirst(int[] data) {
data[0] = 99; // Modifica el array original
}