Lo he usado LinkedHashMap
porque es importante el orden en que las claves ingresaron en el mapa.
Pero ahora quiero obtener el valor de la clave en primer lugar (la primera entrada ingresada) o la última.
¿Debería haber un método como first()
y / last()
o algo así?
¿Necesito tener un iterador para obtener la primera entrada clave? ¡Por eso solía LinkedHashMap
!
¡Gracias!
java
dictionary
linkedhashmap
maiky
fuente
fuente
Respuestas:
La semántica de
LinkedHashMap
sigue siendo la de un Mapa, en lugar de la de unLinkedList
. Conserva el orden de inserción, sí, pero ese es un detalle de implementación, más que un aspecto de su interfaz.La forma más rápida de obtener la "primera" entrada sigue siendo
entrySet().iterator().next()
. Es posible obtener la "última" entrada, pero implicará iterar sobre todo el conjunto de entradas llamando.next()
hasta llegar a la última.while (iterator.hasNext()) { lastElement = iterator.next() }
editar : Sin embargo, si está dispuesto a ir más allá de la API JavaSE, Apache Commons Collections tiene su propia
LinkedMap
implementación, que tiene métodos comofirstKey
ylastKey
, que hacen lo que está buscando. La interfaz es considerablemente más rica.fuente
mylinkedmap.entrySet().iterator().next()
complejidad del tiempo? ¿Es O (1)?¿Puedes intentar hacer algo como (para obtener la última entrada):
fuente
T last = null ; for( T item : linkedHashMap.values() ) last = item;
O algo así. Es O (N) en el tiempo pero O (1) en la memoria.Sé que llegué demasiado tarde, pero me gustaría ofrecer algunas alternativas, no algo extraordinario, sino algunos casos que ninguno mencionó aquí. En caso de que a alguien no le importe tanto la eficiencia pero quiera algo con más simplicidad (tal vez encuentre el último valor de entrada con una línea de código), todo esto se simplificará bastante con la llegada de Java 8 . Proporciono algunos escenarios útiles.
En aras de la exhaustividad, comparo estas alternativas con la solución de matrices que otros usuarios ya mencionaron en esta publicación. Resumo todos los casos y creo que serían útiles (cuando el rendimiento importa o no), especialmente para los nuevos desarrolladores, siempre depende de cada problema.
Posibles alternativas
Uso del método de matriz
Lo tomé de la respuesta anterior para hacer las siguientes comparaciones. Esta solución pertenece a @feresr.
Uso del método ArrayList
Similar a la primera solución con un rendimiento un poco diferente
Reducir método
Este método reducirá el conjunto de elementos hasta obtener el último elemento de la secuencia. Además, solo devolverá resultados deterministas
Método SkipFunction
Este método obtendrá el último elemento de la secuencia simplemente omitiendo todos los elementos antes de que
Alternativa Iterable
Aquí está el código fuente completo
Aquí está la salida con el rendimiento de cada método.
fuente
LinkedHashMap
La implementación actual (Java 8) realiza un seguimiento de su cola. Si el rendimiento es una preocupación y / o el mapa es de gran tamaño, puede acceder a ese campo a través de la reflexión.Debido a que la implementación puede cambiar, probablemente sea una buena idea tener una estrategia alternativa también. Es posible que desee registrar algo si se produce una excepción para que sepa que la implementación ha cambiado.
Podría verse así:
fuente
ClassCastException
al porcatch
si acasotail
no es unEntry
en una subclase (o una implementación futura).Una forma más de obtener la primera y última entrada de un LinkedHashMap es usar el método "toArray" de la interfaz Set.
Pero creo que iterar sobre las entradas en el conjunto de entradas y obtener la primera y la última entrada es un mejor enfoque.
El uso de métodos de matriz conduce a la advertencia de la forma "... necesita una conversión no verificada para ajustarse a ...", que no se puede arreglar [pero solo se puede suprimir mediante la anotación @SuppressWarnings ("sin marcar")].
Aquí hay un pequeño ejemplo para demostrar el uso del método "toArray":
fuente
Está un poco sucio, pero puede anular el
removeEldestEntry
método de LinkedHashMap, que podría ser adecuado para usted como miembro anónimo privado:Por lo tanto, siempre podrá obtener la primera entrada en su
eldest
miembro. Se actualizará cada vez que realice unaput
.También debería ser fácil anular
put
y configuraryoungest
...Sin embargo, todo se rompe cuando comienzas a eliminar entradas; no he encontrado una manera de criticar eso.
Es muy molesto que de otra manera no puedas acceder a la cabeza o la cola de una manera sensata ...
fuente
Quizás algo como esto:
fuente
Sugerencia:
fuente
Recomendaría usar ConcurrentSkipListMap que tiene
firstKey()
ylastKey()
métodosfuente
Para el primer elemento, use
entrySet().iterator().next()
y deje de iterar después de 1 iteración. Para el último, la forma más fácil es preservar la clave en una variable cada vez que haces un map.put.fuente
Aunque LinkedHashMap no proporciona ningún método para obtener el primer, último o cualquier objeto específico.
Pero es bastante trivial conseguirlo:
Establecer al = orderMap.keySet ();
ahora usando iterador en un objeto; Puedes conseguir cualquier objeto.
fuente
Sí, me encontré con el mismo problema, pero afortunadamente solo necesito el primer elemento ... - Esto es lo que hice por él.
Si también necesita el último elemento, buscaría cómo invertir el orden de su mapa, guárdelo en una variable temporal, acceda al primer elemento en el mapa invertido (por lo tanto, sería su último elemento), elimine el variable temporal
Aquí hay algunas buenas respuestas sobre cómo revertir el orden de un hashmap:
Cómo iterar hashmap en orden inverso en Java
Si usa la ayuda del enlace de arriba, por favor denles un voto positivo :) Espero que esto pueda ayudar a alguien.
fuente
a la derecha, debe enumerar manualmente el conjunto de claves hasta el final de la lista vinculada, luego recuperar la entrada por clave y devolver esta entrada.
fuente
fuente