Colecciones y tipos genéricos en Java 1


COLECCIONES
Las colecciones son una especie de arrays de tamaño dinámico. Para usarlas haremos uso del Java Collections Framework (JCF), el cual contiene un conjunto de clases e interfaces del paquete java.util para gestionar colecciones de objetos.

En Java las principales interfaces que disponemos para trabajar con colecciones son: Collection, Set, List, Queue y Map:

  • Collection<E>: Un grupo de elementos individuales, frecuentemente con alguna regla aplicada a ellos.
  • List<E>: Elementos en una secuencia particular que mantienen un orden y permite duplicados. La lista puede ser recorrida en ambas direcciones con un ListIterator. Hay 3 tipos de constructores:
    1. ArrayList<E>: Su ventaja es que el acceso a un elemento en particular es ínfimo. Su desventaja es que para eliminar un elemento, se ha de mover toda la lista para eliminar ese “hueco”.
    2. Vector<E>: Es igual que ArrayList, pero sincronizado. Es decir, que si usamos varios hilos, no tendremos de qué preocuparnos hasta cierto punto.
    3. LinkedList<E>: En esta, los elementos están conectados con el anterior y el posterior. La ventaja es que es fácil mover/eliminar elementos de la lista, simplemente moviendo/eliminando sus referencias hacia otros elementos. La desventaja es que para usar el elemento N de la lista, debemos realizar N movimientos a través de la lista.

    Veamos un ejemplo de List:

  • Set<E>: No puede haber duplicados. Cada elemento debe ser único, por lo que si existe uno duplicado, no se agrega. Por regla general, cuando se redefine equals(), se debe redefinir hashCode(). Es necesario redefinir hashCode() cuando la clase definida será colocada en un HashSet. Los métodos add(o) y addAll(o) devuelven false si o ya estaba en el conjunto.
  • Queue<E>: Colección ordenada con extracción por el principio e inserción por el principio (LIFO – Last Input, First Output) o por el final (FIFO – First Input, First Output). Se permiten elementos duplicados. No da excepciones cuando la cola está vacía/llena, hay métodos para interrogar, que devuelven null. Los métodos put()/take() se bloquean hasta que hay espacio en la cola/haya elementos.
  • Map<K,V>: Un grupo de pares objeto clave-valor, que no permite duplicados en sus claves. Es quizás el más sencillo, y no utiliza la interfaz Collection. Los principales métodos son: put(), get(), remove().
    1. HashMap<K,V>: Se basa en una tabla hash, pero no es sincronizado.
    2. HashTable<K,V>: Es sincronizado, aunque que no permite null como clave.
    3. LinkedHashMap<K,V>: Extiende de HashMap y utiliza una lista doblemente enlazada para recorrerla en el orden en que se añadieron. Es ligeramente más rápida a la hora de acceder a los elementos que su superclase, pero más lenta a la hora de añadirlos.
    4. TreeMap<K,V>: Se basa en una implementación de árboles en el que ordena los valores según las claves. Es la clase más lenta.

    Ejemplo de Map:

  • Otros tipos de colecciones: singleton(), singletonList(), singletonMap(). Devuelven conjunto, lista y mapa inmutables, con un único elemento. Útiles para pasar un elemento a un método que espera una colección.
  • El siguiente código es un ejemplo de Colecciones:

    El resultado que produce este código es el siguiente:

    Para poder iterar sobre ellos, es necesario un objeto Iterator como hemos visto en el ejemplo.

    Para compararlos, es necesario un objeto comparable. Para ello, es necesario que nuestra clase implemente a la clase java.lang.Comparable, y usar el método int compareTo(Object o). El método compareTo() devuelve un entero con las siguientes características:

    • Negativo: Si thisObject < anotherObject
    • Cero: Si thisObject == anotherObject
    • Positivo: Si thisObject > anotherObject

    En este ejemplo comparamos cadenas ignorando mayúsculas y minúsculas, e imprimiendo el resultado por orden alfabético:

    El resultado es el siguiente:

    En este ejemplo utilizamos la interface Comparable para comprobar objetos iguales:

    Y el resultado:

    TIPOS GENÉRICOS
    Los tipos genéricos permiten forzar la seguridad de los tipos, en tiempo de compilación, en las colecciones (u otras clases y métodos que utilicen tipos parametrizados).

    El problema que resuelven es que si al crear una colección de un tipo determinado, pongamos String, yo meto un elemento de tipo entero, entonces me dará una excepción. Los genéricos ayudaron a crear una comprobación de tipo en listas y mapas en tiempo de compilación, anteriormente esto no era posible. Otra cosa que podemos hacer en con los tipos parametrizados o genéricos es crear nuestras propias clases.

    Veamos el problema y la solución con tipos genéricos:

    Es decir, básicamente es un tipo “inventado” al cual le decimos de qué tipo queremos que nos pase los datos y él internamente, hace los diferentes castings que haya que hacerle a los dieferentes elementos de la colección, siendo los tipos de éstos transparentes para nosotros.

    Las convenciones de declaración utilizan la letra T para tipos y E para elementos de una colección. Se puede utilizar más de un tipo parametrizado en una declaración. Por convención los tipos parametrizados son letras solitarias mayúsculas, sin esta convención sería difícil leer el código y decir la diferencia entre una variable parametrizada y una clase ordinaria o un nombre de una interface.

    • E – Elemento (Usado extensivamente en las colecciones en java)
    • K – Key
    • N – Number
    • T – Type
    • V – Value
    • S, U, V etc. – 2nd, 3rd, 4th types

Dejar un Comentario

Un comentario en “Colecciones y tipos genéricos en Java