2009-03-25 6 views
341

Estoy buscando una clase en Java que tenga una asociación de valor-clave, pero sin usar hashes. Aquí es lo que estoy haciendo actualmente:¿Clase de Java que implementa Mapa y mantiene el orden de inserción?

  1. añadir valores a un Hashtable.
  2. Obtenga un iterador para el Hashtable.entrySet().
  3. iterar a través de todos los valores y:
    1. Obtener una Map.Entry para el repetidor.
    2. Cree un objeto del tipo Module (una clase personalizada) según el valor.
    3. Agregue la clase a un JPanel.
  4. Mostrar el panel.

El problema con esto es que no tengo control sobre el orden que consigo los valores de nuevo, por lo que no puede mostrar los valores en el un orden dado (sin disco de codificación de la orden).

me gustaría utilizar una o ArrayListVector para esto, pero más adelante en el código que tenga que agarrar el objeto Module para una clave dada, que no puedo hacer con una o ArrayListVector.

¿Alguien sabe de una clase de Java libre/de código abierto que hará esto, o una manera de obtener valores de Hashtable en función de cuándo se agregaron?

Gracias!

+1

No necesita utilizar entryset/map.entry. Puede iterar sobre claves y valores usando hashtable.keys como una enumeración o usando hashtable.keyset.iterator. –

+4

Me tomé la libertad de cambiar el título, ya que no usar el hash en realidad no es el problema, sino mantener el orden de inserción. –

Respuesta

552

Sugiero un LinkedHashMap o un TreeMap. A LinkedHashMap mantiene las claves en el orden en que se insertaron, mientras que un TreeMap se mantiene ordenado a través de Comparator o el orden natural Comparable de los elementos.

Dado que no tiene que mantener los elementos ordenados, LinkedHashMap debería ser más rápido para la mayoría de los casos; TreeMap tiene O(log n) rendimiento para containsKey, get, put y remove, según los Javadocs, mientras que LinkedHashMap es O(1) para cada uno.

Si su API solo espera un orden de clasificación predecible, a diferencia de un orden de clasificación específico, considere utilizar las interfaces implementadas por estas dos clases, NavigableMap o SortedMap. Esto le permitirá no filtrar implementaciones específicas en su API y cambiar a cualquiera de esas clases específicas o una implementación completamente diferente a voluntad después.

+2

Esto no funcionará para mí porque, según los javadocs, esto solo da valores ordenados (a través de la llamada a values ​​()). ¿Hay alguna manera de obtener instancias de Map.Entry ordenadas? –

+1

@CoryKendall: ¿TreeMap no funciona? Se supone que está ordenado por claves, no por valores. –

+1

Mi error, pensé que los Sets no estaban clasificados. –

1

No sé si es de código abierto, pero después de un poco de google, encontré this implementation of Map using ArrayList. Parece ser Java anterior a la 1.5, por lo que es posible que desee genérico, lo que debería ser fácil. Tenga en cuenta que esta implementación tiene acceso O (N), pero esto no debería ser un problema si no agrega cientos de widgets a su JPanel, que de todos modos no debería.

5

Puede mantener un Map (para búsqueda rápida) y List (para pedido) pero un LinkedHashMap puede ser el más simple. También puedes probar SortedMap p. Ej. TreeMap, que tiene cualquier orden que especifique.

13

Si un mapa inmutable se adapte a sus necesidades entonces no es una biblioteca de Google llamado guava (ver también guava questions)

Guava proporciona una ImmutableMap con orden de iteración especificada por el usuario fiable. Este ImmutableMap tiene un rendimiento O (1) para containsKey, get. Obviamente poner y eliminar no son compatibles.

ImmutableMap objetos se construyen mediante el uso de cualquiera de las elegantes métodos de conveniencia estáticas of() y copyOf() o un objeto Builder.

2

LinkedHashMap devolverá los elementos en el orden en que se insertaron en el mapa cuando itere sobre keySet(), entrySet() o values ​​() del mapa.

Map<String, String> map = new LinkedHashMap<String, String>(); 

map.put("id", "1"); 
map.put("name", "rohan"); 
map.put("age", "26"); 

for (Map.Entry<String, String> entry : map.entrySet()) { 
    System.out.println(entry.getKey() + " = " + entry.getValue()); 
} 

Esto imprimirá los elementos en el orden en que se pusieron en el mapa:

id = 1 
name = rohan 
age = 26 
0

cada vez que necesito para mantener el orden natural de las cosas que son conocidas de antemano, yo uso un EnumMap

las claves serán enumeraciones y puede insertarlas en el orden que desee, pero cuando itere, se repetirá en el orden enum (el orden natural).

Además, al utilizar EnumMap no debería haber colisiones que puedan ser más eficientes.

Realmente encuentro que usar enumMap hace que el código sea legible. Aquí hay example

Cuestiones relacionadas