Dominando Java Collections: Guía Completa de Estructuras de Datos Eficientes
Antes de Java 2, Java ofrecía clases ad-hoc (Dictionary, Vector, Stack, Properties) para almacenar grupos de objetos. Eran útiles pero carecían de un tema central unificador.
El Collections Framework se diseñó con tres objetivos:
- Alto rendimiento: Implementaciones eficientes (arrays dinámicos, listas enlazadas, árboles, tablas hash).
- Interoperabilidad: Diferentes tipos de colecciones funcionan de manera similar.
- Extensibilidad: Fácil extensión/adaptación de colecciones.
Todo el framework gira en torno a un conjunto de interfaces estándar. Se proporcionan implementaciones estándar (LinkedList, HashSet, TreeSet, etc.) y puedes implementar las tuyas.
Arquitectura del Framework
Tres pilares:
- Interfaces: Tipos de datos abstractos que representan colecciones. Permiten manipular colecciones independientemente de su representación. Forman una jerarquía.
- Implementaciones (Clases): Implementaciones concretas de las interfaces. Estructuras de datos reutilizables.
- Algoritmos: Métodos que realizan computaciones útiles (ordenar, buscar) sobre objetos que implementan interfaces de colección. Son polimórficos: mismo método en muchas implementaciones.
Además, define interfaces y clases de Map (pares clave-valor). Aunque no son colecciones estrictamente, están totalmente integradas.
Interfaces de Colección Principales
| Interfaz | Descripción |
|---|---|
Collection | Raíz de la jerarquía; grupos de objetos. |
List | Extiende Collection; colección ordenada con duplicados permitidos. |
Set | Extiende Collection; elementos únicos, sin orden garantizado. |
SortedSet | Extiende Set; elementos ordenados ascendentemente. |
Map | Mapea claves únicas a valores (no extiende Collection). |
Map.Entry | Par clave-valor dentro de un Map (clase interna). |
SortedMap | Extiende Map; claves en orden ascendente. |
Enumeration | Legado; sustituida por Iterator. |
Clases de Implementación Estándar
| Clase | Descripción |
|---|---|
AbstractCollection | Implementa la mayor parte de Collection. |
AbstractList | Extiende AbstractCollection; implementa List. |
AbstractSequentialList | Para acceso secuencial (no aleatorio). |
LinkedList | Lista doblemente enlazada; extiende AbstractSequentialList. |
ArrayList | Array dinámico; extiende AbstractList. |
AbstractSet | Implementa la mayor parte de Set. |
HashSet | Basado en tabla hash; extiende AbstractSet. |
LinkedHashSet | Extiende HashSet; mantiene orden de inserción. |
TreeSet | Árbol balanceado (Red-Black); extiende AbstractSet; ordenado. |
AbstractMap | Implementa la mayor parte de Map. |
HashMap | Tabla hash; extiende AbstractMap. |
TreeMap | Árbol balanceado; extiende AbstractMap; claves ordenadas. |
WeakHashMap | HashMap con claves débiles (GC puede reclamarlas). |
LinkedHashMap | Extiende HashMap; orden de inserción. |
IdentityHashMap | Usa igualdad de referencia (==) en lugar de equals(). |
Las clases Abstract* proporcionan implementaciones esqueléticas para minimizar esfuerzo al crear colecciones personalizadas.
Clases Legacy (java.util)
| Clase | Descripción |
|---|---|
Vector | Array dinámico sincronizado; similar a ArrayList pero thread-safe (legacy). |
Stack | Subclase de Vector; pila LIFO. |
Dictionary | Abstracta; clave-valor; predecesora de Map. |
Hashtable | Implementación concreta de Dictionary; sincronizada. |
Properties | Subclase de Hashtable; claves y valores String. |
BitSet | Array de bits que crece dinámicamente. |
Algoritmos del Framework (Clase Collections)
Métodos estáticos para operar sobre colecciones y maps:
sort(List),sort(List, Comparator)binarySearch(List, key),binarySearch(List, key, Comparator)reverse(List),shuffle(List)min(Collection),max(Collection)fill(List, obj),copy(dest, src)synchronizedCollection(Collection)(vistas thread-safe)unmodifiableCollection(Collection)(vistas de solo lectura)
Pueden lanzar ClassCastException (tipos incomparables) o UnsupportedOperationException (colección inmodificable).
Constantes inmutables: EMPTY_SET, EMPTY_LIST, EMPTY_MAP.
Uso de Iterator
Para recorrer una colección. Iterator permite ciclo, obtener/remover elementos. ListIterator extiende para recorrido bidireccional y modificación en listas.
Métodos Clave de Iterator
hasNext(): ¿Hay siguiente elemento?next(): Retorna siguiente elemento.remove(): Elimina último elemento retornado pornext().
Ejemplo
List list = new ArrayList<>(Arrays.asList("a", "b", "c"));
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
Uso de Comparator
TreeSet y TreeMap mantienen orden. El Comparator define qué significa "ordenado". Permite ordenar una colección de múltiples formas y ordenar clases que no podemos modificar.
Ejemplo: Ordenar Strings por Longitud
Comparator byLength = (s1, s2) -> Integer.compare(s1.length(), s2.length());
TreeSet set = new TreeSet<>(byLength);
set.add("casa");
set.add("a");
set.add("elefante");
// Orden: a, casa, elefante
Resumen
- El framework da acceso a estructuras de datos preempaquetadas y algoritmos.
- Una colección referencia otros objetos. Las interfaces declaran operaciones por tipo.
- Clases e interfaces están en
java.util. - Preferir interfaces como tipos de variable:
Listlist = new ArrayList<>(); - Usar
ArrayListpara acceso aleatorio frecuente;LinkedListpara inserciones/borrados frecuentes en medio. - Usar
HashSetpara unicidad sin orden;TreeSetpara unicidad + orden;LinkedHashSetpara unicidad + orden de inserción. - Usar
HashMappara mapas generales;TreeMappara claves ordenadas;LinkedHashMappara orden de inserción.
Java
- Dominando Colecciones en C#: Tutorial Práctico con Ejemplos del Mundo Real
- Dominar Operadores en Java: Tipos, Sintaxis y Ejemplos Prácticos
- Comentarios en Java: Tipos, Uso y Mejores Prácticas
- Dominar el Bucle for Mejorado en Java: Sintaxis, Ejemplos y Mejores Prácticas
- Dominar Strings en Java: Creación, Métodos y Mejores Prácticas
- Dominando interfaces en Java: Conceptos, implementación y mejores prácticas
- Dominando las clases internas anónimas en Java: Definición, sintaxis y ejemplos prácticos
- Dominando Try‑with‑Resources en Java: Gestión automática de recursos explicada
- Anotaciones en Java explicadas: Tipos, ubicación y ejemplos prácticos
- Aserciones en Java: Guía práctica para detectar bugs y asegurar fiabilidad del código
- Dominando Java Collections: Guía Completa de Estructuras de Datos Eficientes