What is the difference between an ArrayList and a list?

ArrayList vs HashSet en Java: ¿Cuál usar?

18/01/2026

Valoración: 3.72 (3502 votos)

En el vasto ecosistema de Java, las estructuras de datos juegan un papel fundamental en la organización y manipulación de la información. Dentro del framework de Colecciones (Collections Framework), `List` y `Set` son interfaces muy utilizadas, y `ArrayList` y `HashSet` son implementaciones concretas que a menudo generan dudas. Ambas permiten almacenar colecciones de objetos, pero sus características y comportamientos difieren significativamente, impactando directamente en el diseño y rendimiento de nuestras aplicaciones. Entender estas diferencias es crucial para seleccionar la herramienta adecuada para cada tarea.

Does ArrayList allow duplicates?
Duplicates : ArrayList allows duplicate values while HashSet doesn't allow duplicates values. Ordering : ArrayList maintains the order of the object in which they are inserted while HashSet is an unordered collection and doesn't maintain any order.

A primera vista, podrían parecer similares, pero sus principios de diseño y uso previsto son distintos. Mientras una se centra en el orden y el acceso por índice, la otra prioriza la unicidad de los elementos y la eficiencia en operaciones de búsqueda y adición, aunque a costa del orden. Sumérgete con nosotros para explorar a fondo `ArrayList` y `HashSet` y descubrir cuál se adapta mejor a tus necesidades de programación.

Índice de Contenido

¿Qué es un ArrayList en Java?

Un `ArrayList` es una implementación de la interfaz `List`. Esencialmente, se comporta como un array dinámico, lo que significa que puede cambiar su tamaño a medida que se añaden o eliminan elementos. Los elementos en un `ArrayList` se almacenan en un orden específico, que es el orden en que fueron insertados. Cada elemento tiene un índice numérico asociado, comenzando desde cero, lo que permite acceder a ellos de manera rápida y eficiente.

Su base es un array ordinario de Java. Cuando el `ArrayList` necesita más espacio del que su array subyacente puede ofrecer, crea un nuevo array más grande y copia todos los elementos existentes al nuevo array. Este proceso de redimensionamiento puede ser costoso en términos de rendimiento, especialmente si ocurre con frecuencia.

Una característica fundamental de `ArrayList` es que permite almacenar elementos duplicados. Puedes añadir el mismo objeto o valor varias veces, y todos ellos coexistirán en la lista, cada uno en su propia posición indexada. Además, `ArrayList` no impone restricciones sobre la cantidad de valores `null` que puedes añadir.

¿Qué es un HashSet en Java?

Un `HashSet` es una implementación de la interfaz `Set`. La característica principal de una colección que implementa `Set` es que no permite elementos duplicados. Si intentas añadir un elemento que ya existe en el `HashSet`, la operación de adición simplemente fallará y el conjunto permanecerá inalterado (el método `add()` retornará `false`).

A diferencia de `ArrayList`, `HashSet` no mantiene ningún orden específico de los elementos. El orden en que se iteran los elementos de un `HashSet` no está garantizado y puede variar. Esto se debe a su implementación interna, que está respaldada por un `HashMap` (aunque esto es un detalle de implementación y no se expone directamente).

How to manipulate ArrayList in Java?
Modifying ArrayLists in Java An ArrayList can easily be modified using built in methods. To add elements to an ArrayList , you use the add() method. The element that you want to add goes inside of the () . To remove elements from an ArrayList , you use the remove() method.

Debido a que `HashSet` utiliza un mecanismo basado en hash para almacenar elementos (aprovechando los métodos `hashCode()` y `equals()` de los objetos), las operaciones básicas como añadir, eliminar y verificar la existencia de un elemento (`contains()`) suelen ser muy rápidas, con una complejidad de tiempo promedio de O(1). Sin embargo, `HashSet` solo permite un único valor `null`.

Diferencias Clave entre ArrayList y HashSet

Para facilitar la comprensión, comparemos punto por punto las diferencias principales entre estas dos estructuras de datos:

Implementación y Herencia

  • ArrayList implementa la interfaz List. Está respaldado internamente por un array.
  • HashSet implementa la interfaz Set. Está respaldado internamente por un HashMap.

Manejo de Duplicados

  • ArrayListpermite elementos duplicados. Puedes añadir el mismo objeto o valor múltiples veces.
  • HashSetno permite elementos duplicados. Cada elemento en un HashSet debe ser único.

Orden de los Elementos

  • ArrayList mantiene el orden de inserción de los elementos. Los elementos se almacenan en el orden en que se añaden.
  • HashSet no garantiza ningún orden de los elementos. El orden de iteración puede variar.

Acceso a Elementos

  • ArrayList es una colección basada en índices. Puedes acceder, obtener o eliminar elementos utilizando su índice numérico (por ejemplo, get(index), remove(index)).
  • HashSet es una colección basada en objetos. No proporciona métodos para acceder a elementos por índice. Las operaciones se basan en la igualdad de los objetos (por ejemplo, contains(object), remove(object)).

Manejo de Valores Null

  • ArrayList permite añadir cualquier número de valores null.
  • HashSet solo permite añadir un único valor null.

Constructores Disponibles

  • ArrayList tiene tres constructores comunes: ArrayList() (capacidad inicial por defecto), ArrayList(int capacity) (capacidad inicial especificada) y ArrayList(Collection c) (crea una lista con los elementos de otra colección).
  • HashSet tiene cuatro constructores comunes: HashSet(), HashSet(int capacity), HashSet(Collection c) y HashSet(int capacity, float loadFactor) (permite especificar la capacidad inicial y el factor de carga para optimizar el rendimiento).

Complejidad de Tiempo de Operaciones Básicas

La eficiencia de las operaciones es una diferencia crucial, derivada de su implementación interna:

ArrayList:

  • add() (al final): O(1) en promedio (amortizado), pero O(n) en el peor caso cuando se necesita redimensionar el array.
  • get(index): O(1) - acceso constante por índice.
  • remove(index): O(n) - requiere mover los elementos posteriores al índice eliminado.
  • remove(object): O(n) - requiere buscar el objeto y luego mover elementos.
  • contains(object): O(n) - requiere iterar sobre los elementos para encontrar el objeto.

HashSet:

  • add(object): O(1) en promedio. En el peor caso (colisiones extremas en el hash), puede ser O(n).
  • remove(object): O(1) en promedio. En el peor caso O(n).
  • contains(object): O(1) en promedio. En el peor caso O(n).

La tabla comparativa resume estas diferencias:

CaracterísticaArrayListHashSet
InterfazListSet
Implementación InternaArray dinámicoHashMap
Permite DuplicadosNo
Mantiene OrdenSí (inserción)No
AccesoPor Índice (get(index))Por Objeto (contains(object))
Valores NullMúltiplesUno
add() ComplejidadO(1) amortizadoO(1) promedio
get() ComplejidadO(1)No aplica
remove() ComplejidadO(n)O(1) promedio
contains() ComplejidadO(n)O(1) promedio

Ejemplos de Uso

Veamos cómo se usan en la práctica con los ejemplos proporcionados:

Ejemplo de ArrayList

Este código crea un `ArrayList` de enteros, añade elementos, elimina uno por índice e itera sobre los restantes:

// Importaciones necesarias import java.io.*; import java.util.*; class ArrayListTest { public static void main(String[] args) throws IOException { // Tamaño inicial (opcional) int n = 5; // Declarando ArrayList con tamaño inicial n List<Integer> al = new ArrayList<>(n); // Añadiendo elementos al final de la lista for (int i = 1; i <= n; i++) { al.add(i); } // Imprimiendo elementos System.out.println(al); // Eliminar elemento en el índice 3 (que es el número 4) al.remove(3); // Mostrando ArrayList después de la eliminación System.out.println(al); // Imprimiendo elementos uno por uno usando índice for (int i = 0; i < al.size(); i++) { System.out.print(al.get(i) + " "); } } }

Salida Esperada:

[1, 2, 3, 4, 5] [1, 2, 3, 5] 1 2 3 5 

Este ejemplo muestra cómo `ArrayList` mantiene el orden de inserción y cómo se manipula utilizando índices para añadir (`add()`) y eliminar (`remove(index)`).

Ejemplo de HashSet

Este código crea un `HashSet` de enteros, añade elementos, incluyendo uno duplicado, e itera sobre ellos:

// Importaciones necesarias import java.util.HashSet; import java.util.Set; class HashSetDemo { public static void main(String[] args) { // Crear un HashSet Set<Integer> hs = new HashSet<>(); // Añadir elementos al HashSet hs.add(1); hs.add(2); hs.add(3); hs.add(4); // Elemento duplicado - será ignorado hs.add(4); // Mostrando elementos del HashSet (el orden puede variar) for (Integer temp: hs) { System.out.print(temp + " "); } } }

Salida Esperada:

1 2 3 4 

(Nota: El orden `1 2 3 4` es solo *una posible* salida. Podría ser `4 1 2 3`, etc., ya que `HashSet` no garantiza el orden). El ejemplo ilustra claramente que el intento de añadir el duplicado `4` es ignorado, y el conjunto final solo contiene elementos únicos.

¿Cómo Manipular un ArrayList en Java?

Manipular un `ArrayList` es sencillo gracias a sus métodos integrados que operan principalmente sobre los elementos o sus índices. Algunos de los métodos más comunes incluyen:

  • add(E element): Añade el elemento especificado al final de la lista.
  • add(int index, E element): Inserta el elemento especificado en la posición indicada por el índice. Los elementos existentes se desplazan.
  • get(int index): Retorna el elemento en la posición especificada.
  • set(int index, E element): Reemplaza el elemento en la posición especificada con el nuevo elemento.
  • remove(int index): Elimina el elemento en la posición especificada y desplaza los elementos posteriores.
  • remove(Object o): Elimina la primera ocurrencia del objeto especificado de la lista.
  • size(): Retorna el número de elementos en la lista.
  • contains(Object o): Retorna true si la lista contiene el objeto especificado.
  • clear(): Elimina todos los elementos de la lista.

Como se ve en el ejemplo, el método `add()` es fundamental para añadir elementos, simplemente pasando el elemento deseado como argumento.

¿Cuál es la Diferencia entre una List y un ArrayList?

Esta es una pregunta común para quienes se inician en Java. La distinción es simple pero fundamental: `List` es una interfaz, mientras que `ArrayList` es una clase que implementa esa interfaz.

  • List (Interfaz): Define un contrato para colecciones ordenadas (secuencias de elementos). Especifica los métodos que cualquier clase que implemente `List` debe tener (como `add`, `get`, `remove`, `size`, etc., que operan con índices). Otras clases que implementan `List` incluyen `LinkedList` y `Vector`.
  • ArrayList (Clase): Es una implementación concreta y redimensionable de la interfaz `List` respaldada por un array. Proporciona las funcionalidades definidas por la interfaz `List` utilizando la estructura de datos de array dinámico.

En resumen, `List` te dice *qué* puedes hacer (operaciones sobre una secuencia ordenada), mientras que `ArrayList` te dice *cómo* se implementa una de esas secuencias ordenadas (usando un array dinámico).

Does ArrayList allow duplicates?
Duplicates : ArrayList allows duplicate values while HashSet doesn't allow duplicates values. Ordering : ArrayList maintains the order of the object in which they are inserted while HashSet is an unordered collection and doesn't maintain any order.

Preguntas Frecuentes (FAQ)

¿ArrayList permite elementos duplicados?

Sí, ArrayList permite y almacena elementos duplicados. Puedes añadir el mismo objeto o valor varias veces, y cada instancia se mantendrá en su propia posición dentro de la lista, accesible por su índice.

¿HashSet permite elementos duplicados?

No, HashSet no permite elementos duplicados. Si intentas añadir un elemento que ya existe en el HashSet, la operación `add()` no modificará el conjunto y retornará `false`.

¿Cuál es más rápido, ArrayList o HashSet?

Depende de la operación. Para operaciones de añadir, eliminar y verificar existencia (`add`, `remove`, `contains`), HashSet es generalmente más rápido (O(1) promedio) debido a su implementación basada en hash. Para obtener elementos por índice (`get`), ArrayList es muy rápido (O(1)). Sin embargo, para eliminar elementos por valor o verificar existencia, ArrayList es más lento (O(n)).

¿Cuándo debo usar ArrayList y cuándo HashSet?

Usa ArrayList cuando necesites una colección ordenada donde el orden de inserción sea importante, cuando necesites acceder a elementos por su índice, y cuando no te importe (o necesites) permitir elementos duplicados. Usa HashSet cuando necesites una colección que garantice que todos los elementos son únicos y cuando el orden de los elementos no sea relevante. Es ideal para eliminar duplicados de otra colección o para operaciones rápidas de búsqueda (`contains`).

¿Puedo añadir elementos nulos a un ArrayList o HashSet?

Sí. ArrayList permite añadir cualquier número de elementos nulos. HashSet permite añadir un único elemento nulo.

Conclusión

ArrayList y HashSet son dos pilares del Collections Framework de Java, cada uno con sus fortalezas y casos de uso ideales. La elección entre uno y otro depende fundamentalmente de dos requisitos clave: si necesitas permitir elementos duplicados y si el orden de los elementos es importante. ArrayList, como una lista indexada, es excelente para mantener secuencias y acceder a elementos por su posición. HashSet, como un conjunto basado en hash, es insuperable para garantizar la unicidad y realizar búsquedas rápidas. Comprender sus diferencias en implementación, manejo de duplicados, orden, acceso y rendimiento te permitirá tomar decisiones informadas y escribir código Java más eficiente y robusto.

Si quieres conocer otros artículos parecidos a ArrayList vs HashSet en Java: ¿Cuál usar? puedes visitar la categoría Automóviles.

Subir