Pregunta ¿Cómo mantener una lista única en Java?


Cómo crear una lista única en Java.

En este momento estoy usando HashMap<String, Integer> para hacer esto ya que la clave se sobrescribe y, por lo tanto, al final podemos obtener HashMap.getKeySet() que sería único Pero estoy seguro de que debería haber una mejor manera de hacerlo ya que la parte del valor se desperdicia aquí.


74
2017-11-06 21:16


origen


Respuestas:


Puedes usar un Conjunto implementación:

Alguna información de JAVADoc:

Una colección que contiene sin elementos duplicados. Más formalmente, los conjuntos no contienen ningún par de elementos e1 y e2 tales como e1.equals (e2), y como máximo un elemento nulo. Tal como lo implica su nombre, esta interfaz modela la abstracción del conjunto matemático.

Nota: Se debe tener mucho cuidado si los objetos mutables se usan como elementos establecidos. El comportamiento de un conjunto no se especifica si el valor de un objeto se cambia de una manera que afecta a las comparaciones iguales mientras que el objeto es un elemento en el conjunto. Un caso especial de esta prohibición es que no está permitido que un conjunto se contenga a sí mismo como un elemento.

Estas son las implementaciones:

  • HashSet

    Esta clase ofrece un rendimiento de tiempo constante para las operaciones básicas (agregar, eliminar, contener y tamaño), asumiendo que la función de dispersión dispersa los elementos correctamente entre los cubos. La iteración sobre este conjunto requiere un tiempo proporcional a la suma del tamaño de la instancia de HashSet (la cantidad de elementos) más la "capacidad" de la instancia de HashMap de respaldo (el número de segmentos). Por lo tanto, es muy importante no establecer la capacidad inicial demasiado alta (o el factor de carga demasiado bajo) si el rendimiento de la iteración es importante.

    Al iterar un HashSet el orden de los elementos cedidos no está definido.

  • LinkedHashSet

    La tabla Hash y la implementación de la lista vinculada de la interfaz Set, con un orden de iteración predecible. Esta implementación difiere de HashSet en que mantiene una lista doblemente enlazada que se ejecuta a través de todas sus entradas. Esta lista vinculada define el orden de iteración, que es el orden en el que se insertaron los elementos en el conjunto (orden de inserción). Tenga en cuenta que el orden de inserción no se ve afectado si un elemento se vuelve a insertar en el conjunto. (Un elemento e se reinserta en un conjunto s si s.add (e) se invoca cuando s.contains (e) devolvería verdadero inmediatamente antes de la invocación).

    Entonces, el resultado del código de arriba ...

     Set<Integer> linkedHashSet = new LinkedHashSet<>();
     linkedHashSet.add(3);
     linkedHashSet.add(1);
     linkedHashSet.add(2);
    
     for (int i : linkedHashSet) {
         System.out.println(i);
     }
    

    ... necesariamente será

    3
    1
    2
    
  • TreeSet

    Esta implementación proporciona un costo de tiempo de registro (n) garantizado para las operaciones básicas (agregar, eliminar y contener). Por defecto, los elementos devueltos en la iteración se ordenan por su "ordenamiento natural", entonces el código de arriba ...

     Set<Integer> treeSet = new TreeSet<>();
     treeSet.add(3);
     treeSet.add(1);
     treeSet.add(2);
    
     for (int i : treeSet) {
         System.out.println(i);
     }
    

    ... producirá esto:

    1
    2
    3
    

    (También puedes pasar un Comparator instancia a una TreeSet constructor, haciendo que clasifique los elementos en un orden diferente).

    Tenga en cuenta que la ordenación mantenida por un conjunto (independientemente de si se proporciona un comparador explícito o no) debe ser coherente con igual si se trata de implementar correctamente la interfaz Set. (Ver Comparable o Comparator para una definición precisa de consistente con iguales.) Esto es así porque la interfaz Set se define en términos de la operación igual, pero una instancia TreeSet realiza todas las comparaciones de elementos usando su método compareTo (o comparar), por lo tanto dos los elementos que se consideran iguales por este método son, desde el punto de vista del conjunto, iguales. El comportamiento de un conjunto está bien definido, incluso si su orden es inconsistente con los iguales; simplemente no obedece el contrato general de la interfaz Set.


113
2017-11-06 21:18



Quiero aclarar algunas cosas aquí para el póster original al que otros han aludido pero que no han declarado explícitamente. Cuando dices que quieres una Lista Única, esa es la definición misma de un Conjunto Ordenado. Algunas otras diferencias clave entre la interfaz de conjunto y la interfaz de lista son que la lista le permite especificar el índice de inserción. Entonces, la pregunta es, ¿realmente necesita la Interfaz de lista (es decir, la compatibilidad con una biblioteca de terceros, etc.) o puede rediseñar su software para usar la interfaz Establecer? También debe considerar lo que está haciendo con la interfaz. ¿Es importante encontrar elementos por su índice? ¿Cuántos elementos esperas en tu set? Si va a tener muchos elementos, ¿es importante ordenar?

Si realmente necesita una Lista que solo tenga una restricción única, existe la clase Apache Common Utils class org.apache.commons.collections.list.SetUniqueList que le proporcionará la interfaz List y la restricción única. Sin embargo, esto rompe la interfaz de la Lista. Sin embargo, obtendrá un mejor rendimiento de esto si necesita buscar en la lista por índice. Si puede manejar la interfaz Set y tiene un conjunto de datos más pequeño, entonces LinkedHashSet podría ser un buen camino a seguir. Simplemente depende del diseño y la intención de su software.

Nuevamente, hay ciertas ventajas y desventajas para cada colección. Algunas inserciones rápidas pero lentas, algunas tienen lecturas rápidas pero inserciones lentas, etc. Tiene sentido pasar una buena cantidad de tiempo con la documentación de las colecciones para aprender completamente sobre los detalles más finos de cada clase e interfaz.


10
2017-12-14 18:23



Utilizar new HashSet<String> Un ejemplo:

import java.util.HashSet;
import java.util.Set;

public class MainClass {
  public static void main(String args[]) {
    String[] name1 = { "Amy", "Jose", "Jeremy", "Alice", "Patrick" };

    String[] name2 = { "Alan", "Amy", "Jeremy", "Helen", "Alexi" };

    String[] name3 = { "Adel", "Aaron", "Amy", "James", "Alice" };

    Set<String> letter = new HashSet<String>();

    for (int i = 0; i < name1.length; i++)
      letter.add(name1[i]);

    for (int j = 0; j < name2.length; j++)
      letter.add(name2[j]);

    for (int k = 0; k < name3.length; k++)
      letter.add(name3[k]);

    System.out.println(letter.size() + " letters must be sent to: " + letter);

  }
}

8
2017-11-06 21:18



Podrías simplemente usar un HashSet<String> para mantener una colección de objetos únicos. Si el Integer valores en su mapa son importantes, entonces puede usar el containsKey método de mapas para comprobar si su clave ya está en el mapa.


3
2017-11-06 21:17



HashSet<String> (o cualquier Set la implementación puede hacer el trabajo por usted. Set no permita duplicados.

Aquí está javadoc para HashSet.


2
2017-11-06 21:17



Es posible que desee utilizar una de las clases de implementación de java.util.Set<E> Interfaz, p. java.util.HashSet<String>  clase de colección

Una colección que no contiene elementos duplicados. Más formalmente, los conjuntos no contienen ningún par de elementos e1 y e2 tales como e1.equals (e2), y como máximo un elemento nulo. Tal como lo implica su nombre, esta interfaz modela la abstracción del conjunto matemático.


1
2017-11-06 21:17



No sé cuán eficiente es esto, sin embargo me funcionó en un contexto simple.

List<int> uniqueNumbers = new ArrayList<>();

   public void AddNumberToList(int num)
    {
        if(!uniqueNumbers .contains(num)) {
            uniqueNumbers .add(num);
        }
    }

0
2018-06-28 07:49