W3docs

Interfaz Collection en Java

La interfaz raíz Collection en Java y el contrato que heredan cada lista, conjunto y cola.

java.util.Collection<E> es la raíz de la parte del framework que almacena elementos individuales — cada List, Set, Queue y Deque la implementa (la única familia que no lo hace es Map, cuyos elementos son entradas, no valores individuales). Todo lo que puedes hacer "sin importar qué grupo sea" — agregar, eliminar, preguntar contains, iterar, contar, convertir a array, hacer streaming — está declarado aquí. Este capítulo es el contrato: los métodos en los que puedes confiar para cualquier colección, los pocos que pueden lanzar excepciones, y el modelo de iteración que hereda cada implementación.

La jerarquía de un vistazo

Iterable<E>
  └── Collection<E>
        ├── List<E>           — ordered, indexed, duplicates allowed
        ├── Set<E>            — no duplicates
        │     └── SortedSet<E> → NavigableSet<E>
        └── Queue<E>          — "next in line"
              └── Deque<E>    — double-ended queue

Collection extiende Iterable<E>, razón por la que cada colección funciona con el bucle for-each. Las dos especializaciones de CollectionSet y Queue — refinan el contrato; Map tiene su propia raíz.

Métodos principales que tiene toda colección

A continuación se presenta el conjunto completo de métodos de instancia en Collection, agrupados por propósito. Memoriza las categorías en lugar de la lista — una vez que sabes que existe un método llamado removeIf, puedes encontrarlo.

Tamaño y vacuidad

  • int size() — número de elementos.
  • boolean isEmpty()size() == 0 pero a menudo más rápido.

Agregar

  • boolean add(E e) — agrega un elemento. Devuelve true si la colección cambió. (Un Set devuelve false para un duplicado.)
  • boolean addAll(Collection<? extends E> c) — agrega cada elemento de c.

Eliminar

  • boolean remove(Object o) — elimina una ocurrencia de o.
  • boolean removeAll(Collection<?> c) — elimina cada elemento que aparece en c.
  • boolean retainAll(Collection<?> c) — conserva solo los elementos en c (intersección).
  • boolean removeIf(Predicate<? super E> filter) — elimina cada elemento que coincide con el predicado. La forma más limpia de filtrar en el lugar.
  • void clear() — vacía la colección.

Consultar

  • boolean contains(Object o) — prueba de pertenencia.
  • boolean containsAll(Collection<?> c) — prueba de subconjunto.

Iteración y vistas masivas

  • Iterator<E> iterator() — el iterador subyacente; lo que usa for-each.
  • Stream<E> stream() / parallelStream() — abre un Stream sobre los elementos.
  • void forEach(Consumer<? super E> action) — heredado de Iterable. La forma funcional de iteración.

Conversión a array

  • Object[] toArray()
  • <T> T[] toArray(T[] a) y el más nuevo <T> T[] toArray(IntFunction<T[]> generator) (Java 11+) — array tipado.

Esa es la interfaz completa. Cada lista, conjunto y cola que encontrarás en esta parte es simplemente una implementación diferente de esos métodos más algunos propios.

Igualdad y equals / hashCode

Collection.equals(Object) no está definido en la raíz — cada sub-interfaz especifica qué significa la igualdad para ella. List requiere los mismos elementos en el mismo orden; Set requiere los mismos elementos independientemente del orden; Queue no define equals en absoluto (una cola LinkedList y una cola ArrayDeque con el mismo contenido no son iguales porque la comparación recurre a la identidad). No compares colecciones entre familias y esperes simetría.

Los elementos almacenados en una Collection deben tener equals / hashCode coherentes si quieres que contains, remove y (para colecciones basadas en hash) las búsquedas funcionen correctamente. Cubrimos el contrato en el capítulo de equals y hashCode — ese es el prerrequisito para usar Set y Map con tus propias clases.

Operaciones opcionales

Algunas colecciones son no modificables — List.of(1,2,3), Collections.unmodifiableList(list), las vistas devueltas por Map.keySet() en ciertas implementaciones, etc. Aún así implementan Collection, pero llamar a add, remove, clear, o cualquier método mutante lanza UnsupportedOperationException. El Javadoc llama a estas "operaciones opcionales." Es lo más cercano que tiene Java a un rechazo en tiempo de ejecución de partes de una interfaz; el precio es que el compilador no puede detectar el error — lo descubres en el primer lanzamiento.

Una regla segura: si no construiste la colección, trátala como posiblemente no modificable. Si necesitas una copia mutable, haz new ArrayList<>(received) primero.

Iteración: tres formas, un mecanismo subyacente

Cada colección admite tres estilos de iteración, y los tres terminan llamando a iterator():

Collection<String> names = List.of("Ada", "Linus", "Grace");

// 1. for-each — the everyday form
for (String n : names) System.out.println(n);

// 2. forEach with a lambda — declarative
names.forEach(System.out::println);

// 3. Iterator — when you need to remove during iteration
Iterator<String> it = names.iterator();
while (it.hasNext()) {
  String s = it.next();
  if (s.startsWith("L")) it.remove();   // safe; for-each can't do this
}

Por qué las formas 1 y 3 siguen siendo importantes: el bucle for-each no puede modificar la colección subyacente sin lanzar ConcurrentModificationException. Cuando necesitas eliminar mientras iteras, recurres al Iterator explícito. El capítulo de Iteradores más adelante en esta parte cubre el protocolo en detalle.

Álgebra de conjuntos con operaciones masivas

Las operaciones masivas convierten una colección en una calculadora de álgebra de conjuntos (independientemente de si es un Set — también funcionan en List):

Collection<Integer> a = new ArrayList<>(List.of(1, 2, 3, 4));
Collection<Integer> b = List.of(3, 4, 5);

a.addAll(b);                 // union (multiset)
a.retainAll(List.of(3, 4));  // intersection
a.removeAll(List.of(3));     // difference

Estas son la forma segura y sin dependencias de expresar "conservar solo los elementos que también están en b" sin escribir un bucle. Modifican el receptor — si necesitas un resultado inmutable, copia primero.

Un ejemplo completo: cada método, uno al lado del otro

El programa a continuación ejercita cada categoría de método de Collection con el mismo ArrayList, para que puedas verlos en un solo lugar y observar el contrato en acción.

java— editable, runs on the server

Dos cosas que vale la pena destacar de la salida:

  1. remove("red") solo eliminó la primera ocurrencia — ese es el contrato en Collection. Para eliminar todas las coincidencias, usa removeIf (lo viste a continuación, eliminando cada palabra de más de cuatro caracteres).
  2. La UnsupportedOperationException de frozen.add("d") es la regla de "operaciones opcionales" en acción. frozen implementa Collection, por lo que la llamada compila. La implementación eligió no soportarla, y lo descubres en tiempo de ejecución.

Qué sigue

Collection es el contrato abstracto. El primer refinamiento concreto que encontrarás es el que agrega orden e indexación — la interfaz List. Ahí es donde entran en escena el acceso indexado, las sublistas y las operaciones que preservan el orden.

Práctica

Práctica
Tienes una `Collection<String>` y quieres eliminar cada elemento cuya longitud sea mayor que cuatro. ¿Cuál es la forma idiomática de hacerlo en una sola instrucción?
Tienes una `Collection<String>` y quieres eliminar cada elemento cuya longitud sea mayor que cuatro. ¿Cuál es la forma idiomática de hacerlo en una sola instrucción?
Was this page helpful?