Genéricos y Colecciones. Parte 2: Colecciones
sábado, diciembre 24, 2011 at 12:29AM
pplouis in certificacion, certificacion, genericos y colecciones, java, ocjp

En este post se hablara del Java Collections Framework, el cual contiene interfaces y clases para manipular las estructuras de datos que hacen posibles las colecciones de objetos.

 

Con el framework de colecciones de Java los desarrolladores usamos estructuras de datos sin tener que enterarnos de cómo están implementadas. Lo cual ahorra mucho tiempo y nos da la seguridad de que tendremos un performance al menos aceptable.

 

 

¿Qué es una colección?

 

Una colección es un objeto que se utiliza para contener (hacer referencia) a un conjunto de objetos, usualmente del mismo tipo. Estos objetos son comúnmente conocidos como elementos.

 

Algunos ejemplos de colecciones son:

 

 

Qué se puede hacer con una colección

 

Estas son algunas funciones que se pueden realizar utilizando colecciones.

 

 

Clases e interfaces clave

 

Las interfaces del framework de colecciones declaran operaciones que pueden ser usadas genéricamente en varios tipos de colecciones. En el examen de certificación se necesitara saber en base a un requerimiento qué colección se debe usar. Por eso es importante conocer las principales clases e interfaces de este framework. Las interfaces mas importantes para el examen son:

 

Collection

Set

SortedSet

List

Map

SortedMap

Queue

NavigableSet

NavigableMap

 

Las clases mas importantes son:

 

Maps

Sets

Lists

Queues

Utilities

HashMap

HashSet

ArrayList

PriorityQueue

Collections

Hashtable

LinkedHashSet

Vector

 

Arrays

TreeMap

TreeSet

LinkedList

 

 

LinkedHashMap

 

 

 

 

 

No todas las colecciones del Collection Framework implementan la interfaz Collection. Ninguna de las clases e interfaces relacionadas con Map derivan de Collection, aunque pueden ser vistas como colecciones.

 

Nota. Los elementos subrayados no implementan ni derivan de la interfaz Collection.

 

En la siguiente imagen se muestra la herencia de clases para las colecciones.

 



Tip. Los términos Collection y Collections podrían ser confundidos a la hora del examen. Collections (en plural) es una clase con métodos estáticos, mientras que Collection (en singular) es la interfaz donde se declaran los métodos comunes las colecciones.

 

 

Sabores de las colecciones

 

Las colecciones vienen en 4 sabores:

 

 

Aunque hay 4 sub-sabores más.

 

 

Una colección puede ser ordered sin ser sorted. Pero una colección no puede ser sorted sin ser ordered, ya que el sorted es una forma especifica de ordered.

 

A continuación se listan las interfaces del Framework Collections:

 

Interfaz List

 

La interfaz List está implementada por las clases ArrayList, Vector y LinkedList. Ocurre un autoboxing cuando se agregan tipos primitivos a objetos de esas clases, porque ellos solo almacenan referencias a objetos.

 

Características:

 

 

Implementaciones:

 

 

2. Vector

 

3. LinkedList

 

Hay 3 implementaciones de List, ArrayList, Vector y LinkedList. La mayoría de las veces usaremos ArrayList, el cual ofrece acceso posicional de tiempo constante, lo cual es bueno. Esto lo hace porque no tiene que localizar el nodo de cada elemento en la lista. Además de que puede tomar ventaja de System.arraycopy cuando necesita mover múltiples elementos al mismo tiempo. Si frecuentemente agregas elementos al inicio de la lista o haces iteraciones a través de la lista para borrar o agregar elementos, deberías considerar usar LinkedList. Esas operaciones requieren un tiempo constante en una LinkedList y tiempo lineal en un ArrayList. De igual manera, el acceso posicional requiere tiempo lineal en una LinkedList y tiempo constante en un ArrayList.

 

Nota. Siempre es conveniente manejar algoritmos cuya ejecución nos ofrezca un tiempo constante en vez de un tiempo lineal. Esto cuando nos sea posible.

 

 

Interfaz Set

 

Un Set se ocupa de que los elementos en la colección sean únicos (no permite duplicados). El método equals es el que determina si dos objetos son idénticos (en tal caso solo se podrá agregar uno a la colección). Esta interfaz tiene 3 implementaciones.

 

1. HashSet

2. LinkedHashSet

3. TreeSet

 

La implementacion de HashSet es mucho mas rápida que la de TreeSet (tiempo constante vs tiempo logarítmico para la mayoría de las operaciones), pero no nos da un orden en los elementos. Si necesitas usar las operaciones de la interfaz SortedSet, o es requerida una iteración con los valores ordenados, usa la implementación de TreeSet. De otro modo usa HashSet.

 

El LinkedHashSet esta en medio del HashSet y del TreeSet. Esta implementado como un hashtable con una lista ligada y nos provee de una iteración en el orden de inserción de los elementos.

 

Ojo: Cuando uses HashSet o LinkedHashSet, los objetos que agregues a ellos deben sobreescribir el método hashCode(). Si ellos no lo sobreescriben, el metodo hashCode() por default de Object permitirá que se agreguen a una colección que no permite elementos duplicados elementos que tu podrías considerar que son iguales.

 

 

Interfaz Map

 

A los Map le interesan y se fijan en los identificadores únicos. Lo que haces cuando utilizas alguna implementación de Map es mapear una clave única (Id) a un valor especifico, por supuesto de objetos. Es una estructura de datos que utiliza el par clave/valor. Las implementaciones de esta interfaz te permiten realizar búsquedas basadas en un Id o buscar en base a los valores. Los Map confían en el método equals() para determinar si dos objetos son diferentes uno de otro, es decir, si generan el mismo hash code.

 

Esta interfaz tiene 4 implementaciones:

 

1.HashMap

2. Hashtable

3. LinkedHashMap

4. TreeMap

 

Si necesitas las operaciones de SortedMap o una iteración ordenada de la colección según las claves , usa TreeMap. Si tu quieres velocidad y no te importa el orden de iteración, usa HashMap. Si tu quieres el performance de HashMap y una iteración en el orden de inserción usa LinkedHashMap. En lo que respecta a esto, la situación de Map es análoga a Set.

 

 

Interfaz Queue

 

Esta interfaz esta diseñada para contener una lista de objetos que serán procesados en alguna forma especifica (una estructura de datos tipo cola). Aunque otros ordenes son posibles, las colas son usualmente pensadas como un FIFO ( primeras entradas, primeras salidas). Las colas soportan todos los métodos estándar de Collection, y agregan métodos para obtener y ver elementos de una cola. Esta interfaz tiene una implementación, que es la PriorityQueue.

 

PriorityQueue

 

Clase agregada en Java 5. El propósito de la clase PriorityQueue es crear una cola “priority-in, priority-out”. En este tipo de colas los elementos son ordenados de acuerdo a su orden natural (en el cual los elementos que sean ordenados primero, serán accesados primero) o según lo especificado con un comparador (Comparator).

 

Tip. Puedes fácilmente obtener algunas respuestas correctas en el examen si reconoces que, por ejemplo un Map no puede ser una clase que escojas cuando necesitas una colección de pares de clave/valor, ya que Map es una interfaz y no una implementación concreta de una clase. En el examen, si te preguntan sobre una interfaz, piensa en una interfaz y no en una clase que implemente esa interfaz. Y al revés también, si te preguntan por una clase, no respondas escogiendo una interfaz. Pasa mas bien por un tema de concentración y de leer bien la pregunta.

 

La siguiente tabla resume las clases orientadas a colecciones que necesitas entender para el examen.

 




Conclusión

 

El Framework Collection de Java nos proporciona un conjunto de interfaces y clases para poder hacer agrupaciones de objetos. Hay en este conjunto de clases e interfaces, lo necesario para cumplir con prácticamente todos los requerimientos del día a día de un desarrollador. Un punto clave para las colecciones es identificar que clase o que interfacse podemos utilizar dado un requerimiento. Esto lo podemos hacer conociendo la funcionalidad y opciones que ofrecen cada una de las implementaciones de este framework.

 

Guía de secuencia de estudio recomendada sobre este tema

 

Al tener este tema gran cantidad de información, se recomienda estudiar de manera secuencial siguiendo los siguientes pasos.

1) Conocer qué es la interfaz Colection y qué es la clase Collections.

2) Conocer qué métodos proporciona la clase Colection (obtener un elemento, insertar o eliminar un elemento, recorrelo mediante un iterador).

3) Conocer qué clases extienden de este objeto Colecction: Set, List, Map, Queue, y cuáles son las primeras características de los mismos (Set -> elementos ordenados, List -> elementos secuenciales, Map -> clave par / valor, Queue -> objetos de cola de prioridad, primero que entra, primero que sale).

4) Conocer que, de manera transversal, aparece el concepto de tree  (permite ordenación con estructura de árbol), linked (permite potenciar la vinculación entre elementos) y hash (permite la inserción de elementos siguiendo una estructura de Hash). También aparece el concepto de sincronización. Es bueno conocer que, desde mi punto de vista, las colecciones nacieron con las listas, por lo cual este concepto quedo en tres clases: ArrayList, Vector, y LinkedList, y después las interfaces de árbol, hash y linked se aplicaron con más vehemencia sobre los elementos Set y Map. En última instancia tenemos las colas con la implementación de PriorityQueue, que es una parte poco evolucionada además de ciertamente engañosa, en el sentido de que no es una relación FIFO como tal, si no que en este tipo de colas, existe un algoritmo de ordenación donde se da prioridad a los elementos, no existiendo una inserción meramente secuencial en la relación First Input First Output.

5) Conocer las clases que implementan las interfaces anteriores, y conocer las diferencias sutiles existentes entre ellas:

6) No asustarse sobre este tema y hacer bastantes ejercicios, y jugar mucho con ejemplos básicos ;)

 

Article originally appeared on javaHispano (http://www.javahispano.org/).
See website for complete article licensing information.