====== 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 }