2012-04-30 21 views
27

Hola Tengo un LinkedHashMap (llamado info) que contiene pares de nombre/edad (cadena/int). Quiero averiguar, cómo puedo obtener la posición de la clave/valor si ingreso la clave. Por ejemplo, si mi LinkedHashMap veía así {bob = 12, Jeremy = 42, Carly = 21} y me fue a buscar a Jeremy, debe devolver 1 ya que está en la posición 1. Tenía la esperanza de que puedo usar algo como info.getIndex ("jeremy")¿Cómo obtener la posición de clave/valor en LinkedHashMap utilizando su clave

+1

Ver [why-doesnt-linkedhashmap-provide-access-by-index] (http://stackoverflow.com/questions/5666820/why-doesnt-linkedhashmap-provide-access-by-index) – nawfal

Respuesta

22

HashMap implementaciones en general no están pedidas para Iteration.

LinkedHashMap es predictablely clasificadas por Iteration (orden de inserción), pero no expone la interfaz List y una LinkedList (que es lo que refleja el orden de introducción de llave conjunto) no realizar un seguimiento de la posición de índice en sí o bien, es muy in- eficiente para encontrar el índice también. El LinkedHashMap tampoco expone la referencia al interno LinkedList.

El actual "lista enlazada" comportamiento es específico de la implementación. Algunos pueden realmente usar una instancia de LinkedList algunos muchos solo tienen Entry rastrear un anterior y siguiente Entry y usar eso como su implementación . No asumas nada sin mirar la fuente.

El KeySet que contiene las claves no garantiza pedido, así debido a los algoritmos de hash utilizados para la colocación en la estructura de datos de soporte de la HashMap heredado. Entonces no puedes usar eso.

La única manera de hacerlo, sin escribir su propia implementación, es caminar por el Iterator que usa el reflejo LinkedList y mantener un conteo donde se encuentre, esto será muy eficiente con grandes conjuntos de datos.

Solución

Lo que suena como lo que queremos es posiciones de índice de orden original de inserción, que tendría que reflejar las llaves en el KeySet en algo así como un ArrayList, mantenerlo sincronizado con cambios a la HashMap y úselo para encontrar la posición. Crear una subclase de HashMap, digamos IndexedHashMap y agregar esto ArrayList internamente y agregar un .getKeyIndex(<K> key) que delegue en el interno ArrayList.indexOf() es probablemente la mejor manera de hacerlo.

Esto es lo que hace LinkedHashMap pero con un LinkedList que refleja el KeySet en lugar de un ArrayList.

+1

Pensé LinkedHashMap conserva el orden ¿Hay algo que pueda usar que pueda almacenar clave/valor pero retener el orden? – Matt9Atkins

+1

Conserva, * orden * pero no rastrea * posición *. –

+0

@ HernánEche leyó la pregunta y la respuesta para la comprensión, también quieren hacer un seguimiento de la posición, sobre la cual entraré en detalle en mi respuesta. –

0

LinkedHashMap tiene "orden de iteración predecible" (javadoc). Sin embargo, los artículos no conocen su ubicación, por lo que tendrás que repetir la colección para obtenerla. Si mantiene un mapa grande, es posible que desee utilizar una estructura diferente para el almacenamiento.

Editar: aclaró iteración

+0

* "caminar la tecla' Set' no te hará ningún bien, está respaldado por un 'Set', y no está ordenado. La' LinkedList' solo se usa para 'Iterator'. [En caso de duda use la fuente] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/HashMap.java#HashMap.keySet%28%29). –

+0

De hecho, quise decir entrada set. Es por eso que cité el bit de orden de iteración ... uso implícito del iterador. Mala elección de palabras por mi parte –

+0

El primer párrafo en el javadoc dice que está en orden de inserción, que es exactamente lo que preguntó para. Creo que estamos diciendo lo mismo aquí, de todos modos. Las ediciones han hecho su respuesta más clara. –

0

Puede utilizar com.google.common.collect.LinkedListMultimap de la biblioteca Google guayaba.No necesita el comportamiento multimapa de esta clase, lo que desea es que el método keys() garantice que se devuelven en orden de inserción y luego se pueden usar para construir una lista, puede usar el indexOf() para encontrar la posición de índice requerida

9
int pos = new ArrayList<String>(info.keySet()).indexOf("jeremy") 
+1

Afaik the' keySet() ' no está garantizado – membersound

Cuestiones relacionadas