====== 02.5 - Arrays, colecciones y maps ======
===== 2. Colecciones =====
Las **colecciones** son estructuras de datos avanzadas que **pueden cambiar de tamaño dinámicamente**. Parten de la interfaz base ''java.util.Collection''.
Principales métodos comunes:
* ''int size()'': Devuelve el número de elementos.
* ''boolean isEmpty()'': Indica si está vacía.
* ''boolean contains (Object element)'': retorna verdadero si la colección tiene el elemento pasado como parámetro.
* ''boolena add(Object element)'': Añade un elemento.
* ''boolean remove(Object elementt)'': Elimina un elemento.
* ''void clear()'': Vacía la colección.
==== Conjuntos (Set) ====
Un ''Set'' es una colección que **NO permite elementos duplicados**.
Implementaciones más comunes:
* ''HashSet'': Muy rápido. No garantiza ningún orden de los elementos.
* ''LinkedHashSet'': Rápido. Mantiene el orden en el que se insertaron los elementos.
* ''TreeSet'': Ordena los elementos automáticamente según su valor.
Set numbers = new HashSet(); //Una práctica habitual es definir el tipo de datos conjunto como la interfaz genérica (Set)
numbers.add(10);
numbers.add(5);
numbers.add(10); // Devuelve false y NO se añade porque está duplicado
Otra forma más cómoda de inicializar un conjunto (válido a partir de Java 9) es utilizar el método ''of()'':
Set numbers = Set.of(2, 10, 3, 23, 99);
Si inicializamos un conjunto con el método ''of()'', el conjunto que se crea es **inmutable**, es decir, no podemos cambiarlo, con lo que no podremos añadir, eliminar ni modificar elementos.
Para recorrerlo, podemos usar ''for-each'':
for (Integer number : numbers) {
IO.println(number);
}
==== Listas (List) ====
Un ''List'' es una colección ordenada que **SÍ permite elementos duplicados** y cuenta con **acceso posicional mediante índice**.
Implementaciones principales:
* ''ArrayList'': Basada en ''arrays'' redimensionables. Muy rápida para acceder a posiciones concretas (''get'').
* ''LinkedList'': Lista doblemente enlazada. Muy eficiente al insertar o eliminar elementos frecuentemente.
Métodos clave de List:
* ''E get(int index)'': Obtiene un elemento partiendo de su posición (''index'').
* ''E set(int index, E element)'': Cambia el elemento almacenado en una posición de la lista (''index''), por otro (''element'').
* ''void add(int index, E element)'': Inserta un elemento (''element'') en la lista en una posición concreta (''index''), desplazando los existentes. Si le pasamos solo el elemento (''element'') la inserción la hará al final de la lista.
* ''E remove(int index)'': Elimina un elemento indicando su posición (''index'') en la lista.
* ''boolean addAll(int index, Collection extends E> c)'': Inserta una colección pasada por parámetro en una posición de la lista, desplazando el resto de elementos.
* ''int indexOf(Object o)'': Devuelve la posición de un elemento en la lista o $-1$ si el elemento no está en la lista.
* ''int lastIndexOf(Object o)'': Devuelve la última ocurrencia del objeto en la lista (dado que la lista si puede almacenar duplicados) o $-1$ si el elemento no está en la lista.
* ''List subList(int from, int to)'': Genera una sublista (una vista parcial de la lista) con los elementos comprendidos entre la posición inicial (''from'', incluida) y la posición final (''to'', no incluida).
Los elementos de una lista **empiezan a numerarse por 0**. Es decir, que el primer elemento de la lista es el 0.
Las listas se utilizan de forma muy parecida a los conjuntos:
List numbers = new ArrayList<>();
numbers.add(1); // Añade un elemento al final de la lista.
numbers.add(3); // Añade otro elemento al final de la lista.
numbers.add(1,2); // Añade en la posición 1 el elemento 2.
numbers.add(numbers.get(1)+numbers.get(2)); // Suma los valores contenidos en la posición 1 y 2, y lo agrega al final.
numbers.remove(0); // Elimina el primer elementos de la lista.
for (Integer number: numbers)
IO.println("Elemento:" + number); // Muestra la lista.
}
Igual que con los conjuntos, podemos usar el método ''of()'' para crear **listas inmutables**:
List numbers = List.of(1, 3, 5, 67);
===== 3. Maps =====
Un ''Map'' almacena parejas de clave-valor (''Key'' -> ''Value''). Las claves son únicas y sirven para acceder directamente al valor asociado.
Implementaciones principales:
* ''HashMap'': Sin orden específico en las claves.
* ''TreeMap'': Ordena las claves por valor.
* ''LinkedHashMap'': Mantiene el orden de inserción de las claves.
Métodos clave de ''Map'':
* ''V put(K key, V value)'': Asocia el valor (''value'') con la clave (''key'') en el ''map''. Si la clave no existe en el ''map'' crea un nuevo par clave-valor. Si ya existe, reemplazará el valor.
* ''V get(Object key)'': Obtiene el valor asociado a una clave (''key'') ya almacenada en el mapa. Si no existe la clave, retornará ''null''.
* ''V remove(Object key)'': Elimina la clave (''key'') y el valor (''value'') asociado. Retorna el valor asociado a la clave, por si lo queremos utilizar para algo, o ''null'', si la clave no existe.
* ''boolean containsKey(Object key)'': Devuelve ''true'' si el ''map'' tiene almacenada la clave (''key''). En caso contrario devolverá ''false''.
* ''boolean containsValue(Object value)'': Devuelve ''true'' si el ''map'' tiene almacenada el valor (''value''). En caso contrario devolverá ''false''.
* ''int size()'': Devuelve el número de pares clave-valor almacenado en el ''map''.
* ''boolean isEmpty()'': Devuelve ''true'' si el ''map'' está vacío, ''false'' en cualquier otro caso.
* ''void clear()'': Vacía el ''map''.
* ''Set keySet()'': Devuelve el conjunto de claves contenidas en el ''map''.
Map ages = new HashMap();
ages.put("Ana", 20);
ages.put("Pedro", 25);
ages.put("María", 21);
ages.put("Ana", 21); // Actualiza la edad de Ana a 21
for (String name : ages.keySet()) {
IO.println(name + ": " + ages.get(name));
}
Igual que con los conjuntos y las listas, también podemos crear ''maps'' inmutables con el método ''Map.of()''
Map ages = Map.of("Ana", 20, "Pedro", 25, "María", 21);
===== Ejercicios =====
=== Ejercicio 22.a ===
Crea un ''array'' de enteros con los siguientes números:
{1, 2, 3, 5, 8, 13, 21, 34, 55}
Haz que se muestre por pantalla el cuadrado de cada número del ''array'' utilizando un bucle ''for''.
=== Ejercicio 22.b ===
Utiliza un bucle ''for-each'' para mostrar el cuadrado de los números del ejercicio anterior.
=== Ejercicio 22.c ===
Haz que el ''array'' del ejercicio 1.a se modifique con el cuadrado de cada número y muéstralo por pantalla.
=== Ejercicio 23.a ===
Crea un ''array'' de cinco enteros. Haz que la aplicación pida al usuario cada elemento del ''array'' y, al acabar, muéstralo por pantalla.
=== Ejercicio 23.b ===
Modifica el ejercicio anterior para que la aplicación para que el usuario pueda elegir el tamaño del ''array''.
=== Ejercicio 23.c ===
Haz que la inicialización del ''array'' y mostrar los elementos del ejercicio anterior sean dos funciones separadas.
=== Ejercicio 24.a ===
Crea una matriz de 5x8 de ''boolean'' con los siguientes valores:
{true, true, true, true, true},
{true, false, false, false, true},
{true, false, false, false, true},
{true, false, false, false, true},
{true, false, false, false, true},
{true, false, false, false, true},
{true, false, false, false, true},
{true, true, true, true, true}
Haz que se muestre por pantalla la matriz según la siguiente regla:
* Si el valor es ''true'', se mostrará un $0$
* Si el valor es ''false'' se mostrará un espacio en blanco.
Ejemplo de salida:
OOOOO
O O
O O
O O
O O
O O
O O
OOOOO
=== Ejercicio 24.b ===
Crea otra matriz a partir del ejercicio anterior con los siguientes valores:
{false, false, false, false, true},
{false, false, false, true, true},
{false, false, true, false, true},
{false, true, false, false, true},
{true, false, false, false, true},
{false, false, false, false, true},
{false, false, false, false, true},
{false, false, false, false, true}
Muestra las dos matrices por pantalla según las reglas anteriores.
=== Ejercicio 24.c ===
Haz una aplicación que pida un número binario al usuario. El programa mostrará los bits (empezando por el de la derecha) utilizando las matrices anteriores. La aplicación mostrará la frase "No se puede representar el bit" si éste no es un $1$ o un $0$.
=== Ejercicio 24.d ===
Modifica la aplicación anterior para que el usuario introduzca por pantalla un número decimal y la aplicación muestre el número en binario (utilizando los métodos anteriores).
=== Ejercicio 25.a ===
Crea un conjunto de números enteros. Pide por pantalla el tamaño del conjunto, y haz que el usuario vaya metiendo números al conjunto hasta alcanzar el tamaño introducido. Muestra el conjunto final por pantalla.
=== Ejercicio 25.b ===
Modifica la aplicación anterior para que el tamaño del conjunto sea variable. El usuario introducirá números en el conjunto hasta que escriba un $0$. El $0$ no debe formar parte del conjunto final.
=== Ejercicio 25.c ===
Haz que la aplicación muestre la frase "El número está repetido y no se añadirá al conjunto" si el usuario introduce un número que ya existe en el conjunto.
=== Ejercicio 25.d ===
Separa los números en dos conjuntos: pares e impares. Muestra los dos conjuntos resultantes por pantalla.
=== Ejercicio 26.a ===
Haz un programa que contenga una lista de alumnos con los siguientes valores:
("Ana", "Pedro", "Antonio", "Amparo", "Luis", "María")
Por cada alumno, el programa pedirá la nota y mostrará la frase "El alumno nombre_alumno está aprobado con nota_alumno" si la nota es mayor o igual a $5$.
=== Ejercicio 26.b ===
Modifica el programa anterior para que los alumnos aprobados se añadan a otra lista. Muestra la lista de aprobados cuando se hayan introducido todas las notas (no hace falta mostrar la frase anterior por cada alumno aprobado).
=== Ejercicio 26.c ===
Modifica el ejercicio anterior para que la aplicación muestre un menú con las opciones "Introducir alumno" y "Salir". Cuando se introduce un alumno, el programa pedirá el nombre del alumno y su nota. Si la nota es mayor o igual a $5$, se añadirá a una lista de alumnos aprobados. En caso contrario, se añadirá a la lista de suspendidos. Cuando el usuario elija la opción "Salir", el programa mostrará ambas listas (aprobados y suspendidos).
=== Ejercicio 27 ===
Crea un ''Map'' con los nombres de los alumnos y sus notas. El programa deberá pedir la nota de un listados predefinido de alumnos (puedes utilizar los anteriores) y a continuación mostrará el ''Map'' por pantalla.