2012-07-01 15 views
6

Mi pregunta es: ¿Cuál es una forma rápida de determinar si un número está contenido en un Collection para saber si desea agregarlo a la colección y mantener la singularidad. Preferiría no repetir la lista si puedo evitarlo.Una buena manera de almacenar enteros únicos

Tengo un List<Integer> llamado numberList. Quiero que almacene números enteros únicos y nunca permita que se agreguen duplicados. Me gustaría hacer algo como esto:

private void add(int number) { 
    if (!numberList.contains(number)) { 
    numberList.add(number); 
    } 
} 

Pero obviamente esto no funcionará porque numberList contiene una lista de objetos Integer por lo que independientemente del número de cada uno es un objeto único.

Gracias!

+0

Creo que el método 'contains (...)' usa el método 'equals (...)' del objeto para ver si está retenido o no por la colección, por lo que su método anterior también debe evitar los duplicados. –

+0

Huh, tal vez algo más está mal con mi código, que está dando los resultados inesperados a continuación. ¡Gracias por el consejo! – kentcdodds

+1

si su código es como el mío, ¡siempre hay algo * siempre * incorrecto! ¡Vuelve con más información si necesitas ayuda para encontrarla! –

Respuesta

12

Una es almacenar los enteros en un Set<Integer> como un . Los juegos no permiten duplicados.

Editar
Además, el método de la Colección contains(...) utiliza método equals del objeto (...) para ver si está en manos de la colección o no, por lo que su método anterior evitará duplicados también, si es necesario usar una lista como su colección. Pruébelo usted mismo y verá que es así.

Por ejemplo:

List<Integer> numberList = new ArrayList<Integer>(); 
    int[] myInts = {1, 1, 2, 3, 3, 3, 3, 4}; 
    for (int i : myInts) { 
    if (!numberList.contains(i)) { 
     numberList.add(i); 
     } 
    } 

    System.out.println(numberList); 

volverá: [1, 2, 3, 4]

Además, un posible problema con HashSets es que no están ordenados, por lo que si el pedido es importante, tendrá que mirar usando una de las otras variedades de Sets ordenados.

+0

Por curiosidad, ¿qué implementación crees que sería más rápida? ¿Sería más rápido dejar que 'Set' tratara con duplicados o usar' contains' en una Lista antes de agregar? – kentcdodds

+0

@kentcdodds: Creo que el HashSet sería más rápido ya que el hashing es una operación muy rápida, pero no puedo decir con 100% de seguridad ya que nunca he estudiado la gran O para los algoritmos. Pero espera, uno de los científicos informáticos responderá esto pronto, sin dudas. –

+0

¡Gracias por los consejos! – kentcdodds

3

¿No sería la forma más compacta una BitSet? Es eficiente en términos de almacenamiento, ya que se expandirá indefinidamente. Tampoco usará el almacenamiento innecesariamente.

¿Está trabajando en un entorno con múltiples subprocesos? Si es así, hay otras estructuras que pueden ser mejores/más eficientes.

+0

¡Me tienes a mí! Es un entorno de subprocesos múltiples, por lo que estoy haciendo esto. Quiero verificar si un hilo ya ha agregado el número. – kentcdodds

+0

En ese caso, es casi seguro que estés buscando 'ConcurrentHashMap', quizás incluido en un conjunto derivado de [newSetFromMap] (http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html # newSetFromMap% 28java.util.Map% 29) pero siempre puede agregar 'Boolean.TRUE' al' Map' si lo desea. – OldCurmudgeon

+1

BitSet es muy eficiente para pequeños y densos conjuntos de números. Pero 'new BitSet(). Add (Integer.MAXVALUE);' ya asigna 268MB. Por lo tanto, debe usarse con cuidado. – Arne

Cuestiones relacionadas