Colecciones Java: la interfaz de conjuntos

    Introducción

    los Marco de colecciones de Java es un marco fundamental y esencial que cualquier desarrollador de Java fuerte debería conocer como la palma de su mano.

    Una colección en Java se define como un grupo o colección de objetos individuales que actúan como un solo objeto.

    Hay muchas clases de colección en Java y todas ellas extienden el java.util.Collection y java.util.Map interfaces. En su mayoría, estas clases ofrecen diferentes formas de formular una colección de objetos dentro de un solo objeto.

    Colecciones de Java es un marco que proporciona numerosas operaciones sobre una colección: búsqueda, clasificación, inserción, manipulación, eliminación, etc.

    Esta es la primera parte de una serie de artículos de las colecciones de Java:

    • La interfaz de lista
    • La interfaz de conjunto (estás aquí)
    • La interfaz del mapa
    • Las interfaces Queue y Deque

    Conjuntos

    La siguiente interfaz común del marco es java.util.Set.

    Los conjuntos no ofrecen métodos adicionales, aparte de los métodos heredados de Collection interfaz.

    Un conjunto modela la abstracción matemática del conjunto y no puede contener elementos duplicados. Dicho esto, también vale la pena señalar que estos elementos no tienen un orden específico dentro del conjunto:

    List<String> names = Arrays.asList("David", "Scott", "Adam", "Jane", "Scott", "David", "Usman");
    System.out.println(names);
    
    Set<String> uniqueNames = new HashSet<>(names);
    System.out.println(uniqueNames);
    

    Ejecutar este fragmento de código produciría:

    [David, Scott, Adam, Jane, Scott, David, Usman]
    [Adam, David, Jane, Scott, Usman]
    

    Como puede notar, la lista names contiene entradas duplicadas, y el conjunto uniqueNames elimina los duplicados y los imprime sin un orden específico.

    Agregar un elemento

    Utilizando el add() método, similar a Lists podemos agregar objetos a Set:

    Set<String> uniqueNames = new HashSet<>();
    uniqueNames.add("David");
    uniqueNames.add("Scott");
    uniqueNames.add("Adam");
    uniqueNames.add("Jane");
    uniqueNames.add("Scott");
    uniqueNames.add("David");
    uniqueNames.add("Usman");
    
    System.out.println(uniqueNames);
    

    Ejecutar este fragmento de código producirá:

    [Adam, David, Jane, Scott, Usman]
    

    Eliminar elementos

    Usando el booleano remove() método, podemos eliminar el elemento especificado de este conjunto si está presente:

    System.out.println(uniqueNumbers.remove(2));
    
    System.out.println(uniqueNumbers);
    

    Salida:

    true
    [1, 3]
    

    Otra opción es utilizar el clear() método para eliminar todos los elementos del Conjunto:

    List<String> names = Arrays.asList("David", "Scott", "Adam", "Jane", "Scott", "David", "Usman");
    Set<String> uniqueNames = new HashSet<>(names);
    
    uniqueNames.clear();
    System.out.println(uniqueNames);
    

    Ejecutar este fragmento de código produciría:

    []
    

    Alternativamente, podríamos confiar en removeAll() método:

    List<String> names = Arrays.asList("David", "Scott", "Adam", "Jane", "Scott", "David", "Usman");
    List<String> newNames = Arrays.asList("David", "Adam");
    Set<String> uniqueNames = new HashSet<>(names);
    
    uniqueNames.removeAll(newNames);
    System.out.println(uniqueNames);
    

    Ejecutar este fragmento de código produciría:

    [Jane, Scott, Usman]
    

    Es importante notar que el removeAll() el método acepta un Collection como argumento. Esto se puede utilizar para eliminar todos los elementos comunes de dos colecciones diferentes, en este caso un List y un Set.

    También tenga en cuenta que puede utilizar este método para eliminar todos los elementos del Collection sí mismo:

    uniqueName.removeAll(uniqueNames);
    

    Esto, por supuesto, terminará con un conjunto vacío. Sin embargo, este enfoque no se recomienda para llamar al removeAll() El método cuesta mucho más que el clear() método.

    Esto se debe a la removeAll() método que compara cada elemento de la colección de argumentos con la colección que llama al método mientras que clear() simplemente los apunta a todos a null y establece el tamaño en 0.

    Contiene el elemento

    Usando el booleano contains() método con el objeto dado, podemos comprobar si esto Set contiene un elemento especificado:

    List<String> names = Arrays.asList("David", "Scott", "Adam", "Jane", "Scott", "David", "Usman");
    Set<String> uniqueNames = new HashSet<>(names);
    
    System.out.println(uniqueNames.contains("David"));
    System.out.println(uniqueNames.contains("Scott"));
    System.out.println(uniqueNames.contains("Adam"));
    System.out.println(uniqueNames.contains("Andrew"));
    

    Ejecutar este código produciría:

    true
    true
    true
    false
    

    Elementos iterativos

    Lo mismo que con las listas, aunque es posible iterar con for y enhanced-for bucles, es mejor usar las colecciones de Java ‘ Iterator para esta tarea:

    Set<E> set = new TreeSet<E>();
    ...
    for(Iterator<E> iterator = set.iterator(); iterator.hasNext()) {
        E element = iterator.next();
        element.someMethod();
        iterator.remove(element);
    }
    

    Además, Java 8 nos presenta una forma realmente sencilla de imprimir los elementos utilizando referencias de métodos:

    set.forEach(System.out::println);
    

    Recuperando tamaño

    Si desea recuperar el tamaño de un conjunto:

    List<String> names = Arrays.asList("David", "Scott", "Adam", "Jane", "Scott", "David", "Usman");
    Set<String> uniqueNames = new HashSet<>(names);
    
    System.out.println(uniqueNames.size());
    

    Ejecutar este fragmento de código produciría:

    5
    

    Comprobando si está vacío

    Si desea ejecutar una verificación para ver si un conjunto está vacío o no antes de realizar cualquier operación en él:

    List<String> names = Arrays.asList("David", "Scott", "Adam", "Jane", "Scott", "David", "Usman");
    Set<String> uniqueNames = new HashSet<>(names);
    
    System.out.println(uniqueNames.isEmpty());
    

    Ejecutar este fragmento de código produciría:

    false
    

    Implementaciones y diferencias

    HashSet:

    • Basado en HashMap (Llamadas hashCode() en el elemento y busca la ubicación)
    • Buena implementación de propósito general (cambia de tamaño cuando se queda sin espacio)

    TreeSet:

    • Basado en TreeMap (Utiliza un árbol binario con un orden de clasificación obligatorio)
    • Mantiene los elementos en el orden dado

    EnumSets:

    • Implementación especializada para enumeraciones (usa un conjunto de bits basado en el ordinal de la enumeración)
    • Usar al almacenar conjuntos de enumeraciones

    Comparación algorítmica

    Conclusión

    El marco de las Colecciones de Java es un marco fundamental que todo desarrollador de Java debería saber utilizar.

    En el artículo, hemos hablado de la interfaz de conjunto y sus implementaciones, sus ventajas y desventajas, así como las operaciones que seguramente usará en un momento u otro.

    Si está interesado en leer más sobre las interfaces de colección, continúe leyendo – Colecciones Java: Colas, Deques y Pilas (próximamente).

     

    Rate this post
    Etiquetas:

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *