Cómo comprobar si una colección contiene duplicados en Java

JavaJavaBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, aprenderás cómo verificar de manera eficiente la presencia de elementos duplicados dentro de una colección Java. Exploraremos el uso de HashSet, una herramienta poderosa del Marco de Colecciones de Java (Java Collections Framework), para identificar duplicados.

A través de pasos prácticos, primero aprenderás cómo aprovechar la propiedad de elementos únicos de HashSet para detectar duplicados. Luego, descubrirás un método alternativo comparando los tamaños de la colección original y un HashSet creado a partir de ella. Finalmente, examinaremos cómo manejar elementos nulos al verificar duplicados.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/DataStructuresGroup(["Data Structures"]) java(("Java")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["Object-Oriented and Advanced Concepts"]) java/DataStructuresGroup -.-> java/arrays("Arrays") java/DataStructuresGroup -.-> java/collections_methods("Collections Methods") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/arraylist("ArrayList") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/hashset("HashSet") subgraph Lab Skills java/arrays -.-> lab-559941{{"Cómo comprobar si una colección contiene duplicados en Java"}} java/collections_methods -.-> lab-559941{{"Cómo comprobar si una colección contiene duplicados en Java"}} java/arraylist -.-> lab-559941{{"Cómo comprobar si una colección contiene duplicados en Java"}} java/hashset -.-> lab-559941{{"Cómo comprobar si una colección contiene duplicados en Java"}} end

Utilizar HashSet para la verificación de duplicados

En este paso, exploraremos cómo utilizar un HashSet en Java para verificar de manera eficiente la presencia de elementos duplicados dentro de una colección. HashSet es parte del Marco de Colecciones de Java (Java Collections Framework) y es especialmente útil porque almacena elementos únicos y ofrece búsquedas muy rápidas.

Primero, creemos un nuevo archivo Java llamado DuplicateCheck.java en tu directorio ~/project. Puedes hacer esto directamente en el Explorador de Archivos del WebIDE haciendo clic derecho en el área de la lista de archivos y seleccionando "Nuevo Archivo", luego escribiendo DuplicateCheck.java.

Ahora, abre el archivo DuplicateCheck.java en el Editor de Código y agrega el siguiente código:

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class DuplicateCheck {

    public static void main(String[] args) {
        // Create a list with some duplicate elements
        List<String> names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add("Alice"); // Duplicate
        names.add("Charlie");
        names.add("Bob"); // Duplicate

        System.out.println("Original List: " + names);

        // Use a HashSet to find duplicates
        Set<String> uniqueNames = new HashSet<>();
        Set<String> duplicates = new HashSet<>();

        for (String name : names) {
            if (!uniqueNames.add(name)) {
                // If add returns false, the element is already in the set
                duplicates.add(name);
            }
        }

        System.out.println("Duplicates found: " + duplicates);
    }
}

Desglosemos las nuevas partes de este código:

  • import java.util.ArrayList;, import java.util.HashSet;, import java.util.List;, import java.util.Set;: Estas líneas importan las clases necesarias de la biblioteca de utilidades de Java para trabajar con listas y conjuntos.
  • List<String> names = new ArrayList<>();: Esto crea una List llamada names que puede contener objetos String. Utilizamos ArrayList como una implementación específica de la interfaz List.
  • names.add(...): Esto agrega elementos a nuestra lista names. Observa que "Alice" y "Bob" se agregan dos veces.
  • Set<String> uniqueNames = new HashSet<>();: Esto crea un Set llamado uniqueNames utilizando la implementación HashSet. Un Set garantiza que solo contendrá elementos únicos.
  • Set<String> duplicates = new HashSet<>();: Esto crea otro Set para almacenar los elementos duplicados que encontramos.
  • for (String name : names): Este es un bucle for-each que itera a través de cada name en la lista names.
  • if (!uniqueNames.add(name)): El método add() de un HashSet devuelve true si el elemento se agregó correctamente (lo que significa que no estaba ya en el conjunto), y false si el elemento ya estaba presente. El ! niega el resultado, por lo que el código dentro del bloque if se ejecuta solo cuando add() devuelve false, lo que indica un duplicado.
  • duplicates.add(name);: Si se encuentra un duplicado, lo agregamos a nuestro conjunto duplicates.

Guarda el archivo DuplicateCheck.java (Ctrl+S o Cmd+S).

Ahora, abre la Terminal en la parte inferior del WebIDE. Asegúrate de estar en el directorio ~/project. Puedes confirmar esto escribiendo pwd y presionando Enter. La salida debería ser /home/labex/project.

Compila el programa Java utilizando el comando javac:

javac DuplicateCheck.java

Si no hay errores, no deberías ver ninguna salida. Esto significa que la compilación fue exitosa y se ha creado un archivo DuplicateCheck.class en el directorio ~/project. Puedes verificar esto ejecutando el comando ls.

Finalmente, ejecuta el programa Java compilado utilizando el comando java:

java DuplicateCheck

Deberías ver una salida similar a esta:

Original List: [Alice, Bob, Alice, Charlie, Bob]
Duplicates found: [Alice, Bob]

El orden de los elementos en la salida de Duplicates found puede variar porque HashSet no mantiene el orden de inserción.

¡Has utilizado con éxito un HashSet para identificar elementos duplicados en una lista!

Comparar los tamaños de la colección y el conjunto

En el paso anterior, utilizamos un HashSet para encontrar elementos duplicados. Una característica clave de un Set es que solo almacena elementos únicos. Esto significa que si agregas elementos duplicados a un Set, solo se mantendrá una instancia de cada elemento. Esta propiedad es muy útil para tareas como eliminar duplicados de una lista.

En este paso, modificaremos nuestro programa DuplicateCheck.java para demostrar esta propiedad comparando el tamaño de la lista original (que puede contener duplicados) con el tamaño de un HashSet creado a partir de esa lista (que solo contendrá elementos únicos).

Abre el archivo DuplicateCheck.java en el Editor de Código del WebIDE.

Modifica el método main para que se vea así:

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class DuplicateCheck {

    public static void main(String[] args) {
        // Create a list with some duplicate elements
        List<String> names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add("Alice"); // Duplicate
        names.add("Charlie");
        names.add("Bob"); // Duplicate
        names.add("David");

        System.out.println("Original List: " + names);
        System.out.println("Size of Original List: " + names.size());

        // Create a HashSet from the list
        Set<String> uniqueNamesSet = new HashSet<>(names);

        System.out.println("Set created from List: " + uniqueNamesSet);
        System.out.println("Size of Set: " + uniqueNamesSet.size());

        // The difference in size tells us how many duplicates were removed
        int duplicatesCount = names.size() - uniqueNamesSet.size();
        System.out.println("Number of duplicates (excluding first occurrence): " + duplicatesCount);
    }
}

Esto es lo que hemos agregado o cambiado:

  • Agregamos otro nombre, "David", a la lista names para tener una lista un poco más grande.
  • System.out.println("Size of Original List: " + names.size());: Imprimimos el tamaño de la lista original utilizando el método size().
  • Set<String> uniqueNamesSet = new HashSet<>(names);: Esta es una forma conveniente de crear un HashSet directamente a partir de otra Collection (como nuestra ArrayList). Cuando haces esto, el HashSet agrega automáticamente todos los elementos de la lista, y como es un Set, descartará cualquier duplicado.
  • System.out.println("Size of Set: " + uniqueNamesSet.size());: Imprimimos el tamaño del HashSet. Este tamaño representa el número de elementos únicos.
  • int duplicatesCount = names.size() - uniqueNamesSet.size();: Calculamos la diferencia entre el tamaño de la lista y el tamaño del conjunto. Esta diferencia nos dice cuántos elementos eran duplicados (más allá de su primera aparición).

Guarda el archivo DuplicateCheck.java modificado.

Ahora, compila el programa nuevamente en la Terminal:

javac DuplicateCheck.java

Si la compilación es exitosa, ejecuta el programa:

java DuplicateCheck

Deberías ver una salida similar a esta:

Original List: [Alice, Bob, Alice, Charlie, Bob, David]
Size of Original List: 6
Set created from List: [Alice, Bob, Charlie, David]
Size of Set: 4
Number of duplicates (excluding first occurrence): 2

Observa que el tamaño de la lista original es 6, pero el tamaño del HashSet creado a partir de ella es 4. La diferencia (6 - 4 = 2) indica correctamente que había dos nombres duplicados ("Alice" y "Bob" aparecieron una vez después de su primera aparición).

Esto demuestra lo fácil que es utilizar un HashSet para encontrar el número de elementos únicos o el número de duplicados en una colección.

Probar con elementos nulos

En los pasos anteriores, hemos visto cómo HashSet maneja elementos no nulos duplicados. Ahora, exploremos cómo se comporta HashSet cuando intentamos agregar elementos null. Entender cómo las colecciones manejan null es importante porque, si no se maneja con cuidado, a veces puede provocar comportamientos inesperados o errores.

Un HashSet permite un solo elemento null. Si intentas agregar null varias veces, solo se almacenará el primer null.

Modifiquemos nuestro programa DuplicateCheck.java una vez más para probar esto.

Abre el archivo DuplicateCheck.java en el Editor de Código del WebIDE.

Modifica el método main para incluir valores null en la lista:

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class DuplicateCheck {

    public static void main(String[] args) {
        // Create a list with some duplicate and null elements
        List<String> names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add(null); // Add null
        names.add("Alice"); // Duplicate
        names.add("Charlie");
        names.add(null); // Add null again
        names.add("Bob"); // Duplicate
        names.add("David");
        names.add(null); // Add null a third time

        System.out.println("Original List: " + names);
        System.out.println("Size of Original List: " + names.size());

        // Create a HashSet from the list
        Set<String> uniqueNamesSet = new HashSet<>(names);

        System.out.println("Set created from List: " + uniqueNamesSet);
        System.out.println("Size of Set: " + uniqueNamesSet.size());

        // The difference in size tells us how many duplicates were removed
        // Note: This calculation is less straightforward with nulls and duplicates combined
        // int duplicatesCount = names.size() - uniqueNamesSet.size();
        // System.out.println("Number of duplicates (excluding first occurrence): " + duplicatesCount);
    }
}

Aquí, hemos agregado null a la lista names varias veces. También hemos comentado el cálculo del número de duplicados porque se vuelve menos significativo cuando se involucra null y nos estamos centrando en el comportamiento del conjunto con null.

Guarda el archivo DuplicateCheck.java modificado.

Compila el programa en la Terminal:

javac DuplicateCheck.java

Si la compilación es exitosa, ejecuta el programa:

java DuplicateCheck

Deberías ver una salida similar a esta:

Original List: [Alice, Bob, null, Alice, Charlie, null, Bob, David, null]
Size of Original List: 9
Set created from List: [null, Alice, Bob, Charlie, David]
Size of Set: 5

Observa la salida:

  • La Original List muestra todos los elementos, incluyendo los múltiples valores null. Su tamaño es 9.
  • El Set created from List contiene solo elementos únicos. Observa que null aparece solo una vez en el conjunto, incluso aunque se agregó varias veces a la lista. El tamaño del conjunto es 5 (Alice, Bob, Charlie, David y null).

Esto confirma que HashSet permite un solo elemento null y trata las adiciones posteriores de null como duplicados, al igual que cualquier otro elemento.

Ahora has probado con éxito cómo HashSet maneja elementos null. Esto concluye nuestra exploración del uso de HashSet para la verificación de duplicados y la comprensión de su comportamiento con elementos únicos y nulos.

Resumen

En este laboratorio, aprendimos cómo verificar de manera eficiente la presencia de elementos duplicados dentro de una colección Java utilizando un HashSet. Creamos una List con elementos duplicados y luego la recorrimos, intentando agregar cada elemento a un HashSet. Al comprobar el valor de retorno del método add(), que devuelve false si el elemento ya está presente, pudimos identificar y recopilar los elementos duplicados en un HashSet separado. Este método aprovecha la propiedad de elementos únicos y las capacidades de búsqueda rápidas de HashSet para una detección efectiva de duplicados.