Tema 2: Tipos Abstractos de Datos y Arrays en Java
📝 Resumen Ejecutivo
En esta sesión se introdujo el concepto de Tipos Abstractos de Datos (TAD) como modelos teóricos que definen qué hacen los datos sin preocuparse por su implementación interna. Se estableció la distinción con las Estructuras de Datos, que son las implementaciones concretas (eficiencia espacial y temporal), y se profundizó en el uso, declaración y manipulación de Arrays (unidimensionales y bidimensionales) en Java como la estructura fundamental. Finalmente, se realizaron ejercicios prácticos de recorrido de arrays y sobreescritura del método toString para la visualización de objetos.
🔑 Conceptos Clave
- TAD (Tipo Abstracto de Datos): Modelo lógico que define un conjunto de datos y sus operaciones sin especificar la implementación.
- LIFO (Last In First Out): Estructura donde el último en entrar es el primero en salir (Ej. Pila).
- FIFO (First In First Out): Estructura donde el primero en llegar es el primero en salir (Ej. Cola).
- Array (Arreglo): Secuencia ordenada de elementos del mismo tipo con tamaño fijo.
- Complejidad Temporal/Espacial: Medida del coste de tiempo y memoria de una estructura de datos.
- Método
toString: Método de la claseObjectque debe ser sobreescrito para mostrar una representación legible de un objeto.
📘 Desarrollo del Temario
1. Repaso Práctico: Visualización de Objetos (toString)
Antes de entrar en el tema nuevo, es crucial entender cómo visualizar objetos en la consola, ya que por defecto Java imprime un identificador de memoria poco útil.
- Problema: Al imprimir un objeto directamente (
System.out.println(objeto)), se hereda el método de la claseObject, mostrando algo ininteligible. - Solución: Se debe sobreescribir el método
toString.- En Eclipse:
Source->Generate toString(). - Esto permite formatear la salida, por ejemplo:
return "Complex [re=" + re + ", im=" + im + "]";.
- En Eclipse:
2. Tipos Abstractos de Datos (TAD)
Un TAD define el comportamiento lógico de los datos. Es una abstracción que facilita el diseño de algoritmos.
- Definición: Conjunto de datos y operaciones sobre ellos, independientemente de la implementación.
- No contiene datos en sí, es una representación abstracta.
- Se centra en el qué se hace, no en el cómo.
- Operaciones habituales: Creación (vacío), Inserción, Extracción y Búsqueda.
Clasificación de TADs habituales
- Lista: Colección secuencial (añadir, eliminar).
- Pila (Stack) - LIFO: Last In, First Out. El último elemento que entra es el primero que sacamos. > Ejemplo Verbal: Imaginad una pila de platos o añadir bolitas en un tubo vertical; la última que metes es la primera que tienes que sacar.
- Cola (Queue) - FIFO: First In, First Out. > Ejemplo Verbal: Como la cola de la panadería. El primero que llega es el primero que es atendido y sale.
- Árboles y Grafos: Estructuras más complejas.
Importancia y Ejemplo Real
Los TADs permiten diseñar software en un nivel de abstracción alto y facilitan la reutilización.
Ejemplo de la Vida Real (El Restaurante): Imaginad una cola de clientes en un restaurante.
- Es un TAD porque define datos (clientes) y operaciones (encolar, desencolar, ver quién es el siguiente). * Abstracción: No importa si la cola se gestiona en una hoja de papel, en una App o físicamente; la lógica es la misma.
3. Estructuras de Datos
Si el TAD es el "qué", la Estructura de Datos es el "cómo".
- Definición: Implementaciones concretas de TADs que definen con precisión cómo se almacenan los datos y se realizan las operaciones.
- Métricas de Eficiencia: Al concretar el almacenamiento, surgen dos costes:
- Complejidad Espacial: Cuánto espacio (memoria) consume.
- Complejidad Temporal (Big-O): Cuánto tiempo tarda una operación.
- ¡OJO AL DATO!: No es lo mismo que un algoritmo tarde 10 segundos a que tarde 3 segundos. Buscamos siempre la opción más óptima.
4. Arrays en Java (Unidimensionales)
Características Fundamentales
- Secuencia Ordenada: Elementos del mismo tipo base colocados uno tras otro. "Ordenada" se refiere a la posición secuencial, no a que los valores estén ordenados de menor a mayor.
- Tipado: El tipo base puede ser primitivo (
int) o referenciado (Objetos). - Tamaño Fijo: Se define al crearlo y no se puede modificar posteriormente.
- Naturaleza: En Java, un array es un objeto.
Declaración e Inicialización
Existen dos sintaxis principales, ambas válidas:
int[] miArray = new int[5];(Estilo Java estándar).int miArray[] = new int[5];(Estilo heredado de C).
Nota: Se puede declarar como
nully crear el espacio en memoria después:int[] array; array = new int[5];.
Acceso y Recorrido
- Índices: El acceso es por posición (indexado). Empieza en 0 y termina en N-1.
- Atributo Length: Los arrays tienen un atributo público
lengthque indica su capacidad.
Formas de Recorrer un Array:
- Bucle
forclásico: Usando un índiceidesde 0 hastaarray.length. - Bucle
forEach: Sintaxis simplificada para lectura. "Por cada elemento en miArray...".for (int elem : miArray) { System.out.println(elem); }
Ejercicio Práctico 1: Operaciones con Arrays
El profesor plantea un ejercicio donde se tienen arrays \(A\) y \(B\).
- \(A\): Secuencia \(1, 2... 10\).
- \(B\): Secuencia negativa \(-1, -2... -10\).
- \(C\): Suma de \(A + B\).
Lógica de resolución explicada: Para llenar \(B\) eficientemente, se puede tomar el valor de \(A\) y negarlo en el mismo bucle: $\(B[i] = - (A[i])\)$ Al sumar \(A[i]\) y \(B[i]\) (siendo uno el negativo del otro), el resultado en \(C\) siempre será 0.
5. Arrays Bidimensionales (Matrices)
En Java, un array 2D es realmente un array de arrays.
- Sintaxis:
int[][] tabla = new int[3][3];. - Visualización: Se puede ver como una tabla donde el primer índice es la Fila y el segundo la Columna.
- Desigualdad: Al ser arrays de arrays, técnicamente las filas podrían tener longitudes diferentes (aunque al usar
new int[N][M]se crean cuadradas por defecto).
Recorrido (Doble For)
Para recorrer una matriz completa, se necesita un bucle anidado.
- El bucle exterior controla las filas (
i). - El bucle interior controla las columnas (
j).
Explicación del Profesor: Imaginad un array encima de otro. El primer
forespera a que termine el segundofor(recorrer toda la fila) antes de saltar a la siguiente fila.
Ejemplo de acceso:
miArray[0][0] accede al primer elemento de la primera fila.
🧐 Preguntas de Autoevaluación
- Diferencia clave: ¿Cuál es la diferencia principal entre un TAD y una Estructura de Datos?
- Concepto: Si añado los elementos A, B y C (en ese orden) a una Pila (Stack), ¿cuál es el primer elemento que saldrá al extraer uno? ¿Por qué?
- Java Arrays: Si declaro
int[] numeros = new int[5];, ¿cuál es el índice del último elemento accesible? ¿Qué pasa si intento acceder anumeros[5]? - Lógica 2D: En un array bidimensional
matriz[i][j], ¿qué representa habitualmente laiy qué representa laj? - Debug: ¿Por qué es necesario sobreescribir el método
toStringen una clase Java si queremos imprimir sus objetos por consola?