È possibile ottenere elementi da HashMap dalla sua posizione?


99

Come recuperare un elemento da HashMap dalla sua posizione, è possibile?


11
Cosa intendi per "posizione"? Gli hashmap non sono ordinati, quindi non hanno la solita nozione di "posizione" che si otterrebbe con qualcosa come un vettore.
Sabato

1
Intendi con il suo ordine di inserzione o qualche altro ordinamento?
Mark Elliot

Risposte:


94

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.


16
Questo non risponde davvero alla domanda. Le altre risposte di seguito sono più utili.
forresthopkinsa

6
Con tutto il rispetto, questo cita la documentazione che risponde direttamente alla domanda
Wayne

1
Anche se l'ordine non è costante nel tempo, potrebbe comunque essere possibile recuperare uno dei membri da una data posizione.
Principiante

Io non seguo Spiegare?
Wayne

Il collegamento HashMap è interrotto / 404.
Raf

109

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);

2
È sempre necessario creare un'istanza di una copia delle chiavi da HashMap ??
Richard

questo creerà un nuovo oggetto ArrayList ogni volta che recuperiamo un valore, portando a perdite di memoria
NullByte08

48

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 ] );
}

1
Più semplice devo dire ... Invece di convertire ogni cosa, stai usando solo keyset. Superbo
kirtan403

19

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]);

Nota che arr [i] dovrebbe essere cambiato in: keys [i]
Mohsen Abasi

Ok, ho le stringhe come chiavi della mappa, per averne una, la seconda parte sarà:String myKey = keys[i].toString();
Orici

12

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.


27
che preserverà l'ordine, ma non potrai comunque accedere agli elementi in base al loro indice. Dovresti iterare
Bozho

questo collegamento è a una vecchia versione dell'API. Suggerirei di collegarsi a un'API Java 6 o 7.
jzd

6

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.


3

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;
}

3

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.


2

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


2

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.


2

puoi usare il codice seguente per ottenere la chiave: String [] keys = (String[]) item.keySet().toArray(new String[0]);

e ottieni l'oggetto o l'elenco che si inserisce in HashMap con la chiave di questo elemento in questo modo: item.get(keys[position]);


2

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);

1

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.


0

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.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.