2009-05-13 5 views
17

Digamos que quiero poner palabras en una estructura de datos y quiero tener búsquedas de tiempo constante para ver si la palabra está en esta estructura de datos. Todo lo que quiero hacer es ver si la palabra existe. ¿Utilizaría un HashMap (containsKey()) para esto? HashMap s usa combinaciones de clave-> valor, pero en mi caso no tengo ningún valor. Por supuesto, podría usar null para el valor, pero incluso null toma espacio. Parece que debería haber una mejor estructura de datos para esta aplicación.Java hashmaps sin el valor?

La colección podría ser utilizada potencialmente por varios subprocesos, pero como los objetos contenidos en la colección no cambiarían, no creo que tenga un requisito de sincronización/concurrencia.

¿Alguien puede ayudarme?

Respuesta

41

Use HashSet en su lugar. Es una implementación hash de Set, que se usa principalmente para describir exactamente lo que describes (un conjunto desordenado de elementos).

+0

Si tuviera que usar algo como hashSet, ¿significa eso que no puedo usar cadenas? hashSet.add ("clave"); hashSet.contains ("clave"); // falso, ¿verdad? Dado que las dos claves son objetos separados? – jbu

+0

, no, vuelve verdadero. Hashset es perfecto – jbu

+4

Debería poder usar cadenas perfectamente, porque String tiene su propia implementación de hashCode() que devuelve el mismo hash para las cadenas que son iguales. Referencia: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html#hashCode() –

6

Desea utilizar una Colección que implementa la interfaz Establecer, probablemente HashSet para obtener el rendimiento que indicó. Ver http://java.sun.com/javase/6/docs/api/java/util/Set.html

+0

Si tuviera que usar algo como hashSet, ¿significa eso que no puedo usar cadenas? hashSet.add ("clave"); hashSet.contains ("clave"); // falso, ¿verdad? Dado que las dos claves son objetos separados? – jbu

+0

no, vuelve verdadero. Hashset es perfecto – jbu

+0

jbu, va a utilizar primero hashCode() y luego es igual a() para verificar la membresía (este último para verificar colisiones). Para objetos de la biblioteca estándar, como String, estás en buena forma. Si define sus propios objetos, asegúrese de que hashCode() y equals() estén definidos correctamente. –

1

Aparte de Set s, en algunas circunstancias, es posible que desee convertir un Map en un Set con Collections.newSetFromMap(Map<E,Boolean>) (algunos Map s no permitir null valores, de ahí el Boolean).

6

Probablemente desee utilizar un java.util.Set. Las implementaciones incluyen java.util.HashSet, que es el conjunto equivalente de HashMap.

Incluso si los objetos contenidos en la colección no cambian, es posible que tenga que hacer la sincronización. ¿Es necesario agregar objetos nuevos al conjunto después de pasar el conjunto a un hilo diferente? Si es así, puede usar Collections.synchronizedSet() para hacer que el conjunto sea seguro para subprocesos.

Si tiene un Mapa con valores, y tiene algún código que solo quiere tratar el Mapa como un Conjunto, puede usar Map.entrySet() (aunque tenga en cuenta que entrySet devuelve una vista de Conjunto de las claves en el Mapa, si el Mapa es mutable, el Mapa se puede cambiar a través del conjunto devuelto por entrySet).

6

En general, utilizaría una implementación de Set, y generalmente HashSet. Si necesitó acceso simultáneo, ConcurrentHashSet proporciona un reemplazo directo que brinda acceso concurrente y seguro, incluida la iteración segura en el conjunto.

Recomendaría en cualquier caso referirse a él simplemente como un conjunto en todo su código, excepto en el lugar donde lo construye; de esta forma, es más fácil incluir una implementación para la otra si más adelante lo requiere.

Incluso si el conjunto es de sólo lectura, si se usa de un hilo que no sea el que lo crea, es necesario pensar en segura publicación (es decir, asegurándose de que cualquier otra thread ve el conjunto en un estado consistente: recuerde que cualquier escritura de memoria, incluso en constructores, no está garantizada para estar disponible para otros hilos cuando o en el modo esperado, a menos que tome medidas para garantizar esto).Esto se puede hacer por las dos características siguientes:

  • asegurándose de que la única referencia (s) para el conjunto están en final fields;
  • asegurándose de que realmente es cierto que ningún hilo modifica el conjunto.

Puede ayudar a garantizar esto último utilizando el contenedor Collections.unmodifiableSet(). Esto le da una vista inmodificable del conjunto dado, por lo que siempre que no haya otra referencia "normal" al conjunto de escapes, está a salvo.

-1

como todos dijeron HashSet es probablemente la solución más simple pero no tendrá una búsqueda de tiempo constante en un HashSet (porque las entradas pueden estar encadenadas) y almacenará un objeto ficticio (siempre el mismo) para cada entrada ...

Para obtener información here a list of data structures quizás encuentre la que mejor se adapte a sus necesidades.

Cuestiones relacionadas