Almacenamiento de objetos (Contenedores)

Resumen del capítulo 11 (Almacenamiento de objetos) del "Libro Thinking in Java (4ta Edición)".

Introducción

La biblioteca java.util posee un conjunto bastante completo de clases contenedoras. Existen cuatro tipo básicos: List, Set, Queue y Map (lista, conjunto, cola y mapa). Los contenedores proporcionan formas más sofisticadas (que las matrices) de almacenar objetos.
La biblioteca de contenedores Java toma la idea de “almacenamiento de los objetos” y la divide en dos conceptos distintos, expresados mediante las interfaces básicas de la biblioteca:
  • Collection: una secuencia de elementos individuales a los que se aplica una o más reglas.
    - List: almacena los elementos en la forma en la que fueron insertados.
    - Set: no puede tener elementos duplicados.
    - Queue: produce los elementos en el orden determinado por una disciplina de cola.
  • Map: un grupo de parejas de objetos clave-valor, que permite efectuar búsquedas de valores utilizando una clase. Un mapa permite buscar un objeto utilizando otro objeto. También se lo denomina matriz asociativa o diccionario.
Estas interfaces utilizan tipos genéricos, es decir, se debe especificar el tipo de objeto/s que almacenará el contenedor. Esto se realiza a través de corchetes angulares que rodean los parámetros de tipo.
De ser posible, se debe intentar escribir la mayor parte del código para que se comunique con estas interfaces. El único lugar donde se debería especificar el tipo concreto del contenedor es en la creación del mismo.
Ver ejemplo: Main01.java

Existen métodos de utilidad en las clases Arrays y Collections de java.util que añaden grupos de elementos a una colección:
  • Collections.addAll (Collection c, T… elements): toma un objeto de tipo Collection como primer argumento y una lista de valores separados por coma. Añade los elementos a la colección.
  • Arrays.asList (T… a): toma una lista de valores separados por coma y lo transforma en un objeto List.
Ver ejemplo: Main02.java

List

Las listas garantizan que los elementos se mantengan en una secuencia concreta. La interface List añade varios métodos a Collection que permiten la inserción y la eliminación de elementos en mitad de una lista.
Existen dos tipos de objetos List:
  • ArrayList: Es el que mejor permite acceder a los elementos de forma aleatoria, pero que resulta más lento a la hora de insertar y eliminar elementos en mitad de una lista.
  • LinkedList: Proporciona un acceso secuencial óptimo, siendo las inserciones y borrados en mitad de una lista enormemente rápidos. Resulta relativamente lento para los accesos aleatorios, pero tiene muchas más funcionalidades que ArrayList.
Métodos de la interface:
  • boolean contains(Object o): Permite averiguar si un objeto se encuentra dentro de la lista.
  • boolean remove(Object o): Permite eliminar un objeto, pasando la referencia al mismo.
  • int indexOf(Object o): Pasando como parámetro una referencia a un objeto, devuelve el número de índice en el que ese objeto está almacenado.
Estos últimos tres métodos utilizan el método equals() para realizar sus operaciones. Es decir, sobrescribiendo este método (perteneciente a la clase Object) se puede alterar el funcionamiento de estas operaciones.
  • List subList(int fromIndex,int toIndex): Permite crear una sublista (respaldada) a partir de otra lista de mayor tamaño. Los cambios efectuados en la lista devuelta se verán reflejados en la lista original, y viceversa.
  • boolean containsAll(Collection c): Verifica si los elementos pertenecen a la lista.
  • boolean retainAll(Collection c): Es una operación de intersección de conjuntos, el comportamiento resultante depende de la implementación del método equals().
  • boolean removeAll(Collection c): Elimina de la lista todos los objetos que estén en el argumento de tipo List. También opera de manera distinta dependiendo del método equals().
  • boolean isEmpty(): Devuelve true si la lista se encuentra vacía.
  • void clear(): Elimina todos los elementos de la lista.
  • E set(int index, E element): Se encarga de sustituir el elemento situado en el índice indicado (el primer argumento) con el segundo argumento.
Ver ejemplo: Main03.java

Set

Los objetos de tipo Set (conjuntos) no permiten almacenar más de una instancia de cada objeto, impide la duplicación. Para insertar un nuevo elemento se debe verificar la no pertenencia, por este motivo la operación más importante de un conjunto suele ser el de la búsqueda. Set tiene la misma interfaz que Collection, por lo que no existe ninguna funcionalidad adicional.
Existen tres tipos de contenedores Set:
  • HashSet: Utiliza el mecanismo de hash para acelerar las búsquedas de elementos.
  • TreeSet: Mantiene los elementos ordenados en una estructura de datos de tipo árbol rojo-negro. Este objeto es útil para mantener los objetos ordenados.
  • LinkedHashSet: Es un subtipo de HashSet, por lo tanto también emplea una función hash para acelerar las búsquedas, pero mantiene los elementos en orden de inserción utilizando una lista enlazada.
Ver ejemplo: Main04.java

Queue

Una cola es normalmente un contenedor de tipo FIFO (first-in, first-out). El orden en el que se introduzcan los elementos coincidirá con el orden en que estos serán extraídos. Las colas son especialmente importantes en la programación concurrente.
Existen dos tipos de contenedores Queue:
  • LinkedList: Dispone de métodos para soportar el comportamiento de una cola e implementa la interface Queue, por lo que un objeto LinkedList puede utilizarse como implementación de Queue.
  • PriorityQueue: Es una implementación automática de una cola con prioridad. Este tipo de contenedor implica que el elemento que va a continuación será aquel que tenga una necesidad mayor (la prioridad más alta). El mecanismo de ordenación predeterminado utiliza el orden natural de los objetos de la cola, pero se puede modificar dicho elemento proporcionando otro objeto Comparator.
Arroja una excepción Retorna un valor especial
Inserta boolean add(E e) boolean offer(E e)
Elimina E remove() E poll()
Obtiene E element() E peek()

Ver ejemplo: Main05.java

Map

Los mapas permiten asociar objetos con otros objetos. Es decir, almacenan parejas de clave-valor. En los contenedores no se pueden almacenar primitivas, por eso la característica autoboxing convierte las primitivas en sus correspondientes objetos envoltorios. Este tipo de contenedores puede expandirse fácilmente para que sean multidimensionales, basta con definir un objeto Map cuyos valores sean también mapas.
Existen tres tipos de contenedores Map:
  • HashMap: Están diseñados para un acceso rápido.
  • TreeMap: Mantiene sus claves ordenadas y no es tan rápido como el anterior.
  • LinkedHashMap: Mantiene sus elementos en orden de inserción, pero proporciona un acceso rápido con mecanismos de hash.
Métodos de la interface:
Ver ejemplo: Main06.java

Iteradores

Iterator
Es una interface que permite desplazarse a través de una secuencia y seleccionar cada uno de los objetos que la componen.
  • boolean hasNext(): Permite ver si hay más objetos en la secuencia.
  • E next(): Obtiene el siguiente objeto de la secuencia.
  • void remove(): Elimina el último elemento devuelto por el iterador.
ListIterator
Es un subtipo más potente de Iterator que solo se genera mediante las clases List. ListIterator es bidireccional, puede generar los índices de los elementos siguiente y anterior, en relación al lugar de la lista hacia el que el iterador está apuntando y también posee otras funcionalidades. Los métodos que adiciona esta interface son:
  • boolean hasPrevious(): Realiza la misma acción que hasNext() pero en sentido contrario.
  • E previous(): Idem next() pero en sentido contrario.
  • int nextIndex(): Obtiene el número de índice del elemento siguiente.
  • int previousIndex(): Obtiene el número de índice del elemento anterior.
  • void set(E e): Permite sustituir el elemento al que apunta por el iterador.
  • void add(E e): Inserta un elemento en la lista.
NOTA: NO HAY NECESIDAD DE UTILIZAR LAS CLASES ANTIGUAS Vector, Hashtable y Stack.

0 comentarios:



Publicar un comentario en la entrada

Este blog dejo de ser mantenido el día 12/02/2010. Para cualquier consulta o comentario realizarlo a través del sitio http://onj2ee.blogspot.com/