Solución:
HashMap
las implementaciones en general no están ordenadas para Iteration
.
LinkedHashMap
es predeciblemente ordenado para Iteration
(orden de inserción) pero no expone el List
interfaz y un LinkedList
(que es lo que refleja el orden de inserción del conjunto de claves) tampoco rastrea la posición del índice en sí, tampoco es muy eficiente encontrar el índice. los LinkedHashMap
no expone la referencia al interno LinkedList
cualquiera.
El actual “Lista enlazada” el comportamiento es específico de la implementación. Algunos pueden usar una instancia de
LinkedList
algunos muchos acaban de tener
Entry
rastrear un anterior y siguienteEntry
y utilícelo como su implementación. No asuma nada sin mirar la fuente.
los KeySet
que contiene las claves no garantiza el orden también debido a los algoritmos hash utilizados para la ubicación en la estructura de datos de respaldo de los heredados HashMap
. Entonces no puedes usar eso.
La única forma de hacer esto, sin escribir su propia implementación, es recorrer el Iterator
que usa el reflejo LinkedList
y mantenga un recuento de dónde se encuentra, esto será muy poco eficiente con grandes conjuntos de datos.
Solución
Lo que parece que quieres es posiciones de índice de orden de inserción original, tendrías que reflejar las claves en el KeySet
en algo como un ArrayList
, manténgalo sincronizado con las actualizaciones de HashMap
y utilícelo para encontrar la posición. Creando una subclase de HashMap
, decir IndexedHashMap
y agregando esto ArrayList
internamente y agregando un .getKeyIndex(<K> key)
que delega al interno ArrayList
.indexOf()
es probablemente la mejor manera de hacerlo.
Esto es lo que LinkedHashMap
lo hace pero con un LinkedList
reflejando el KeySet
en lugar de un ArrayList
.
int pos = new ArrayList<String>(info.keySet()).indexOf("jeremy")
Vi una sugerencia de uno de los duplicados de esta pregunta en
¿Cómo obtener valor de LinkedHashMap basado en el índice, no en la clave?
y me gustó la sugerencia descrita como pseudocódigo de @schippi en los comentarios. Pensé que algún código Java funcional podría ser útil para otros en este enfoque
import java.util.ArrayList;
import java.util.LinkedHashMap;
public class IndexedLinkedHashMap<K,V> extends LinkedHashMap<K,V> {
/**
*
*/
private static final long serialVersionUID = 1L;
ArrayList<K> al_Index = new ArrayList<K>();
@Override
public V put(K key,V val) {
if (!super.containsKey(key)) al_Index.add(key);
V returnValue = super.put(key,val);
return returnValue;
}
public V getValueAtIndex(int i){
return (V) super.get(al_Index.get(i));
}
public K getKeyAtIndex(int i) {
return (K) al_Index.get(i);
}
public int getIndexOf(K key) {
return al_Index.indexOf(key);
}
}