Come recuperare un elemento da HashMap dalla sua posizione, è possibile?
Come recuperare un elemento da HashMap dalla sua posizione, è possibile?
Risposte:
HashMaps non mantiene l'ordine:
Questa classe non fornisce garanzie sull'ordine della mappa; in particolare, non garantisce che l'ordine rimanga costante nel tempo.
Dai un'occhiata a LinkedHashMap , che garantisce un ordine di iterazione prevedibile.
Utilizzare una LinkedHashMap e quando è necessario recuperare in base alla posizione, convertire i valori in un ArrayList.
LinkedHashMap<String,String> linkedHashMap = new LinkedHashMap<String,String>();
/* Populate */
linkedHashMap.put("key0","value0");
linkedHashMap.put("key1","value1");
linkedHashMap.put("key2","value2");
/* Get by position */
int pos = 1;
String value = (new ArrayList<String>(linkedHashMap.values())).get(pos);
Se vuoi mantenere l'ordine in cui hai aggiunto gli elementi alla mappa, usa LinkedHashMapinvece di HashMap.
Ecco un approccio che ti permetterà di ottenere un valore dal suo indice nella mappa:
public Object getElementByIndex(LinkedHashMap map,int index){
return map.get( (map.keySet().toArray())[ index ] );
}
Se, per qualche motivo, devi restare con hashMap, puoi convertire il keySet in un array e indicizzare le chiavi nell'array per ottenere i valori nella mappa in questo modo:
Object[] keys = map.keySet().toArray();
Puoi quindi accedere alla mappa come:
map.get(keys[i]);
String myKey = keys[i].toString();
Usa LinkedHashMap:
Implementazione di tabelle hash ed elenchi collegati dell'interfaccia Map, con ordine di iterazione prevedibile. Questa implementazione differisce da HashMap in quanto mantiene un elenco a doppio collegamento che attraversa tutte le sue voci.
Usa LinkedHashMap e usa questa funzione.
private LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();
Definisci in questo modo e.
private Entry getEntry(int id){
Iterator iterator = map.entrySet().iterator();
int n = 0;
while(iterator.hasNext()){
Entry entry = (Entry) iterator.next();
if(n == id){
return entry;
}
n ++;
}
return null;
}
La funzione può restituire la voce selezionata.
Suppongo che per "posizione" ti riferisca all'ordine in cui hai inserito gli elementi in HashMap. In tal caso si desidera utilizzare una LinkedHashMap. La LinkedHashMap non offre tuttavia un metodo di accesso; dovrai scriverne uno simile
public Object getElementAt(LinkedHashMap map, int index) {
for (Map.Entry entry : map.entrySet()) {
if (index-- == 0) {
return entry.value();
}
}
return null;
}
Un altro approccio funzionante consiste nel trasformare i valori della mappa in un array e quindi recuperare l'elemento in index. L'esecuzione di test di 100.000 elementi mediante ricerche di indice in LinkedHashMap di 100.000 oggetti utilizzando i seguenti approcci ha portato ai seguenti risultati:
//My answer:
public Particle getElementByIndex(LinkedHashMap<Point, Particle> map,int index){
return map.values().toArray(new Particle[map.values().size()])[index];
} //68 965 ms
//Syd Lambert's answer:
public Particle getElementByIndex(LinkedHashMap<Point, Particle> map,int index){
return map.get( (map.keySet().toArray())[ index ] );
} //80 700 ms
Tutto sommato il recupero di elementi per indice da LinkedHashMap sembra essere un'operazione piuttosto pesante.
HashMap e la struttura dati sottostante, le tabelle hash, non hanno la nozione di posizione. A differenza di un LinkedList o Vector, la chiave di input viene trasformata in un "bucket" in cui viene memorizzato il valore. Questi bucket non sono ordinati in un modo che abbia senso al di fuori dell'interfaccia HashMap e come tali, gli elementi che metti in HashMap non sono in ordine nel senso che ti aspetteresti con le altre strutture dati
HashMap non ha il concetto di posizione, quindi non c'è modo di ottenere un oggetto in base alla posizione. Gli oggetti in Maps vengono impostati e acquisiti tramite chiavi.
Per impostazione predefinita, java LinkedHasMap non supporta l'acquisizione di valore in base alla posizione. Quindi suggerisco di andare con personalizzatoIndexedLinkedHashMap
public class IndexedLinkedHashMap<K, V> extends LinkedHashMap<K, V> {
private ArrayList<K> keysList = new ArrayList<>();
public void add(K key, V val) {
super.put(key, val);
keysList.add(key);
}
public void update(K key, V val) {
super.put(key, val);
}
public void removeItemByKey(K key) {
super.remove(key);
keysList.remove(key);
}
public void removeItemByIndex(int index) {
super.remove(keysList.get(index));
keysList.remove(index);
}
public V getItemByIndex(int i) {
return (V) super.get(keysList.get(i));
}
public int getIndexByKey(K key) {
return keysList.indexOf(key);
}
}
Quindi puoi usare questa LinkedHasMap personalizzata come
IndexedLinkedHashMap<String,UserModel> indexedLinkedHashMap=new IndexedLinkedHashMap<>();
PER aggiungere valori
indexedLinkedHashMap.add("key1",UserModel);
Per getValue in base a index
indexedLinkedHashMap.getItemByIndex(position);
HashMaps non consente l'accesso in base alla posizione, conosce solo il codice hash e può recuperare il valore se può calcolare il codice hash della chiave. TreeMaps ha una nozione di ordinamento. Le mappe di Linkedhas mantengono l'ordine in cui sono entrate nella mappa.
Puoi provare a implementare qualcosa del genere, guarda:
Map<String, Integer> map = new LinkedHashMap<String, Integer>();
map.put("juan", 2);
map.put("pedro", 3);
map.put("pablo", 5);
map.put("iphoncio",9)
List<String> indexes = new ArrayList<String>(map.keySet()); // <== Parse
System.out.println(indexes.indexOf("juan")); // ==> 0
System.out.println(indexes.indexOf("iphoncio")); // ==> 3
Spero che questo funzioni per te.