Wie kann man ein Element anhand seiner Position aus HashMap abrufen? Ist das überhaupt möglich?
Wie kann man ein Element anhand seiner Position aus HashMap abrufen? Ist das überhaupt möglich?
Antworten:
HashMaps behält die Reihenfolge nicht bei:
Diese Klasse übernimmt keine Garantie für die Reihenfolge der Karte. Insbesondere kann nicht garantiert werden, dass die Bestellung über die Zeit konstant bleibt.
Schauen Sie sich LinkedHashMap an , das eine vorhersehbare Iterationsreihenfolge garantiert.
Verwenden Sie eine LinkedHashMap und konvertieren Sie die Werte in eine ArrayList, wenn Sie sie nach Position abrufen müssen.
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);
Wenn Sie die Reihenfolge beibehalten möchten, in der Sie die Elemente zur Karte hinzugefügt haben, verwenden Sie LinkedHashMap
im Gegensatz zu nur HashMap
.
Hier ist ein Ansatz, mit dem Sie einen Wert anhand seines Index in der Karte ermitteln können:
public Object getElementByIndex(LinkedHashMap map,int index){
return map.get( (map.keySet().toArray())[ index ] );
}
Wenn Sie sich aus irgendeinem Grund an die HashMap halten müssen, können Sie das keySet in ein Array konvertieren und die Schlüssel im Array indizieren, um die Werte in der Map wie folgt zu erhalten:
Object[] keys = map.keySet().toArray();
Sie können dann wie folgt auf die Karte zugreifen:
map.get(keys[i]);
String myKey = keys[i].toString();
Verwendung LinkedHashMap
:
Implementierung der Hash-Tabelle und der verknüpften Liste der Map-Schnittstelle mit vorhersagbarer Iterationsreihenfolge. Diese Implementierung unterscheidet sich von HashMap dadurch, dass eine doppelt verknüpfte Liste geführt wird, die alle Einträge durchläuft.
Verwenden Sie LinkedHashMap und verwenden Sie diese Funktion.
private LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();
Definieren Sie so und.
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;
}
Die Funktion kann den ausgewählten Eintrag zurückgeben.
Ich gehe davon aus, dass Sie sich mit 'Position' auf die Reihenfolge beziehen, in der Sie die Elemente in die HashMap eingefügt haben. In diesem Fall möchten Sie eine LinkedHashMap verwenden. Die LinkedHashMap bietet jedoch keine Zugriffsmethode. Sie müssen eine wie schreiben
public Object getElementAt(LinkedHashMap map, int index) {
for (Map.Entry entry : map.entrySet()) {
if (index-- == 0) {
return entry.value();
}
}
return null;
}
Ein anderer Arbeitsansatz besteht darin, Kartenwerte in ein Array umzuwandeln und dann das Element am Index abzurufen. Der Testlauf von 100 000 Elementen durch Indexsuche in LinkedHashMap von 100 000 Objekten unter Verwendung der folgenden Ansätze führte zu folgenden Ergebnissen:
//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
Alles in allem scheint das Abrufen von Elementen per Index aus LinkedHashMap eine ziemlich schwere Operation zu sein.
HashMap - und die zugrunde liegende Datenstruktur - Hash-Tabellen haben keine Vorstellung von Position. Im Gegensatz zu einer LinkedList oder einem Vektor wird der Eingabeschlüssel in einen 'Bucket' umgewandelt, in dem der Wert gespeichert wird. Diese Buckets sind nicht in einer Weise angeordnet, die außerhalb der HashMap-Schnittstelle sinnvoll ist. Daher sind die Elemente, die Sie in die HashMap einfügen, nicht in dem Sinne angeordnet, wie Sie es von den anderen Datenstrukturen erwarten würden
HashMap hat kein Positionskonzept, daher gibt es keine Möglichkeit, ein Objekt nach Position zu ermitteln. Objekte in Karten werden gesetzt und über Schlüssel abgerufen.
Sie können den folgenden Code verwenden, um den Schlüssel zu erhalten:
String [] keys = (String[]) item.keySet().toArray(new String[0]);
und erhalten Sie ein Objekt oder eine Liste, die mit dem Schlüssel dieses Elements wie folgt in HashMap eingefügt werden:
item.get(keys[position]);
Standardmäßig unterstützt Java LinkedHasMap das Abrufen von Werten nach Position nicht. Also schlage ich vor, mit maßgeschneiderten zu gehenIndexedLinkedHashMap
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);
}
}
Dann können Sie diese angepasste LinkedHasMap als verwenden
IndexedLinkedHashMap<String,UserModel> indexedLinkedHashMap=new IndexedLinkedHashMap<>();
Werte hinzufügen
indexedLinkedHashMap.add("key1",UserModel);
Um den Wert nach Index zu erhalten
indexedLinkedHashMap.getItemByIndex(position);
HashMaps erlauben keinen Zugriff nach Position, kennen nur den Hash-Code und können den Wert abrufen, wenn sie den Hash-Code des Schlüssels berechnen können. TreeMaps haben einen Begriff der Bestellung. Linkedhas-Karten behalten die Reihenfolge bei, in der sie in die Karte eingegeben wurden.
Sie können versuchen, so etwas zu implementieren. Schauen Sie sich Folgendes an:
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
Ich hoffe das funktioniert bei dir.