====== Las colecciones ======

Las colecciones en Java son estructuras de datos dinámicas que permiten almacenar listas o
colecciones de datos de un tipo determinado. Además, proporcionan una API muy completa de operaciones para poder realizar sobre toda la colección. Se pueden considerar como una evolución de los //arrays// ya que éstos son estáticos y tienen una operativa más básica. Además, los diferentes tipos de colecciones permiten afinar el comportamiento de cada una de ellas de forma que podremos elegir la que más
nos convenga para cada caso. Existen, por ejemplo, colecciones de datos en las que los elementos están automáticamente ordenados en todo momento (''TreeSet'') u otras que no admiten elementos repetidos (''HashSet''). Otras estructuras mantienen el orden de los elementos (''LinkedList'' o ''ArrayList'') mientras que en otras esa información no es relevante (''HashMap'')

Se les conoce con el nombre de genéricos porque son estructuras ya disponibles en la API de Java pero de forma genérica, por lo que se les debe pasar un tipo de datos para convertirlos en una colección de un tipo determinado. Asi, en el momento de la declaración tendremos que indicar el tipo de datos que almacenará dicha colección.

<code java>
LinkedList<Libro> listaLibros = new LinkedList<Libro>();
// Desde la verisón 8 de Java podemos utilizar el 'diamante' 
// y omitir el tipo al instanciar
LinkedList<Libro> listaLibros = new LinkedList<>();
</code>

Es posible no indicar el tipo de dato de la colección, crenado lo que se conoce como una colección //raw//, aunque no está recomendado porque evita que el compilador de Java pueda hacer chequeos de tipo en tiempo de compilación, lo que facilita mucho el trabajo con este tipo de estructuras.

Existe numerosos tipos de datos para almacenar colecciones con diferentes características. En esta sección veremos algunas de las más utilizadas: ''LinkedList'', ''ArrayList'' y ''HashMap''. También veremos como funcionan las pilas y las colas, para las que Java proporciona los tipos ''Stack'' y ''Queue'' , respectivamente.

Además, existe una serie de interfaces y clases como ''List'', ''Collection'' o ''Arrays'' de la que extienden o implementan estas estructuras de colección, lo que permite que además existan operaciones que permiten que se puedan hacer operaciones que combinen distintos tipos de colección y otras estructuras de datos como los arrays.


<figure>
{{ comparison.jpg }}
<caption>Colecciones en Java</caption></figure>

===== La clase LinkedList =====

La clase ''LinkedList'' es una lista doblemente enlazada, que permite almacenar una colección de objetos, obtenerlos, eliminarlos y algunas operaciones para acceder a los mismos. Acceder al primer y último elemento, entre otros, son operaciones muy directas en este tipo de colección.

Entre las operaciones que se pueden realizar con un ''LinkedList'' las más comunes son las siguientes:

=== Añadir un elemento ===

<code java>
LinkedList<Libro> listaLibros = new LinkedList<>();
. . .
Libro libro = new Libro(. . .);
listaLibros.add(libro);
</code>

=== Añadir un elemento al principio ===

<code java>
LinkedList<Libro> listaLibros = new LinkedList<>();
. . .
Libro libro = new Libro(. . .);
listaLibros.addFirst(libro);
</code>

=== Añadir un elemento al final ===

<code java>
LinkedList<Libro> listaLibros = new LinkedList<>();
. . .
Libro libro = new Libro(. . .);
listaLibros.addLast(libro);
</code>

=== Añadir toda una colección al final ===

<code java>
LinkedList<Libro> listaLibros = new LinkedList<>();
LinkedList<Libro> otraListaLibros = new LinkedList<>();
. . .
listaLibros.addAll(otraListLibros);
</code>

=== Obtener un elemento ===

<code java>
Libro unLibro = listaLibros.get(4);
</code>

=== Obtener el primer/último elemento ===

<code java>
Libro primerLibro = listaLibros.getFirst();
Libro ultimoLibro = listaLibros.getLast();
</code>

=== Eliminar (y obtener) el primer/último elemento ===

<code java>
Libro primerLibro = listaLibros.removeFirst();
Libro ultimoLibro = listaLibros.removeLast();
</code>

=== Eliminar todos los elementos ===

<code java>
listaLibros.clear();
</code>

=== Obtener el tamaño de la colección (número de elementos) ===

<code java>
int tamano = listaLibros.size();
</code>

=== Obtener un array estáticos con los elementos de la colección ===

<code java>
Libro[] libros = listaLibros.toArray();
</code>

===== La clase ArrayList =====

La clase ''ArrayList'' permite definir arrays dinámicos. Son colecciones de datos dinámicas con el acceso y funcionamiento de un array,
puesto que sólo es posible recuperar cada elemento a partir de la posición del mismo.

Entre las operaciones que se pueden realizar con un \verb ArrayList  las más comunes son las siguientes:

=== Añadir un elemento ===

<code java>
ArrayList<Libro> listaLibros = new ArrayList<>();
. . .
Libro libro = new Libro(. . .);
listaLibros.add(libro);
</code>

=== Añadir toda una colección al final ===

<code java>
ArrayList<Libro> listaLibros = new ArrayList<>();
ArrayList<Libro> otraListaLibros = new ArrayList<>();
. . .
listaLibros.addAll(otraListLibros);
</code>

=== Obtener un elemento ===

<code java>
Libro unLibro = listaLibros.get(4);
</code>

=== Eliminar un libro ===

<code java>
Libro libroEliminado = listaLibros.remove(4);
</code>

=== Eliminar todos los elementos ===

<code java>
listaLibros.clear();
</code>

=== Obtener el tamaño de la colección (número de elementos) ===

<code java>
int tamano = listaLibros.size();
</code>

=== Obtener un array estáticos con los elementos de la colección ===

<code java>
Libro[] libros = listaLibros.toArray();
</code>

===== La clase HashMap =====

Es una tabla hash que implementa el interfaz ''Map'' de Java, lo que le convierte en una estructura de colección que almacena objetos asociados a una clave. Este tipo de colecciones, a diferencia de los anteriores, no garantiza el orden de los elementos, puesto que éstos se pueden obtener solamente utilizando la clave que se asocio al mismo en el momento de añadirlo.

=== Añadir un elemento (pareja clave-valor) ===

<code java>
HashMap<String, Libro> libros = new HashMap<>();
Libro libro = new Libro(. . .);
libros.add(libro.getTitulo(), libro);
</code>

=== Obtener un elemento ===

<code java>
Libro unLibro = libros.get(tituloLibro);
</code>

=== Comprobar si existe un elemento (a través de su clave) ===

<code java>
libros.containsKey(tituloLibro)
</code>

=== Eliminar todos los elementos ===

<code java>
libros.clear();
</code>

=== Eliminar un elemento ===

<code java>
libros.remove(tituloLibro);
</code>

=== Obtener una colección con todos los valores ===

<code java>
Collection<Libro> losLibros = libros.values()
</code>

=== Obtener una colección con todas las claves ===

<code java>
Set<String> losTitulos = libros.keySet();
<code java>

=== Obtener el número de elementos del HashMap ===

<code java>
libros.size();
</code>

===== Las Pilas =====

Las Pilas son colecciones de datos donde éstos se colocan //apilándolos// y sólo puede ser retirado el elemento que se encuentra encima de la pila. Siguen el principio [[https://es.wikipedia.org/wiki/Last_in,_first_out|LIFO]] (Last In First Out) donde el último elemento en llegar a la colección es el primero en salir de la misma.

=== Añadir un elemento ===

<code java>
Stack<Libro> pilaLibros = new Stack<>();
Libro libro = new Libro(. . .);

pilaLibros.push(libro);
</code>

=== Retirar un elemento de la pila ===

<code java>
Libro libro = pilaLibros.pop();
</code>

=== Obtener, sin retirar, el elemento de lo alto de la pila ===

<code java>
Libro libro = pilaLibros.peek();
</code>

=== Obtener la posición de un elemento (posicion >= 1) ===

\begin{lstlisting}[language=java]
int posicion = pilaLibros.search(libro);
\end{lstlisting}

=== Comprobar el tamaño de la pila ===

<code java>
int tamano = pilaLibros.size();
</code>

===== Las Colas =====

Las colas son colecciones donde los elementos son gestionados según el principio [[https://es.wikipedia.org/wiki/First_in,_first_out|FIFO]] (First In First Out). Funcionan, básicamente, como la //cola del cine//. El primer elemento que llega a la cola será el primero en salir. Si un elemento se añade a la cola, tendrá que esperar a que salgan todos los que le preceden para salir él.

En Java, la clase ''LinkedList'' implementa el interfaz ''Queue'' y proporciona una cola FIFO a través de los métodos ''add(Object)'' y ''poll()'' para retirar el primer elemento.

----

====== Ejemplos ======

----

(c) 2019-{{date>%Y}} Santiago Faci