Comment récupérer un élément de HashMap par sa position, est-ce possible du tout?
Comment récupérer un élément de HashMap par sa position, est-ce possible du tout?
Réponses:
Les HashMaps ne conservent pas l'ordre:
Cette classe ne donne aucune garantie quant à l'ordre de la carte; en particulier, il ne garantit pas que l'ordre restera constant dans le temps.
Jetez un œil à LinkedHashMap , qui garantit un ordre d'itération prévisible.
Utilisez un LinkedHashMap et lorsque vous avez besoin de récupérer par position, convertissez les valeurs en 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);
Si vous souhaitez conserver l'ordre dans lequel vous avez ajouté les éléments à la carte, utilisez LinkedHashMap
plutôt que juste HashMap
.
Voici une approche qui vous permettra d'obtenir une valeur par son index dans la carte:
public Object getElementByIndex(LinkedHashMap map,int index){
return map.get( (map.keySet().toArray())[ index ] );
}
Si, pour une raison quelconque, vous devez vous en tenir à hashMap, vous pouvez convertir le keySet en tableau et indexer les clés du tableau pour obtenir les valeurs de la carte comme ceci:
Object[] keys = map.keySet().toArray();
Vous pouvez ensuite accéder à la carte comme:
map.get(keys[i]);
String myKey = keys[i].toString();
Utilisez LinkedHashMap
:
Implémentation de table de hachage et de liste liée de l'interface Map, avec ordre d'itération prévisible. Cette implémentation diffère de HashMap en ce qu'elle maintient une liste à double lien parcourant toutes ses entrées.
Utilisez LinkedHashMap et utilisez cette fonction.
private LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();
Définissez comme ceci et.
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 fonction peut renvoyer l'entrée sélectionnée.
Je suppose que par «position», vous faites référence à l'ordre dans lequel vous avez inséré les éléments dans le HashMap. Dans ce cas, vous souhaitez utiliser un LinkedHashMap. Le LinkedHashMap n'offre cependant pas de méthode d'accesseur; vous devrez en écrire un comme
public Object getElementAt(LinkedHashMap map, int index) {
for (Map.Entry entry : map.entrySet()) {
if (index-- == 0) {
return entry.value();
}
}
return null;
}
Une autre approche de travail consiste à transformer les valeurs de la carte en un tableau, puis à récupérer l'élément à l'index. Un test de 100 000 éléments par recherche d'index dans LinkedHashMap de 100 000 objets utilisant les approches suivantes a conduit aux résultats suivants:
//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
Dans l'ensemble, récupérer un élément par index à partir de LinkedHashMap semble être une opération assez lourde.
HashMap - et la structure de données sous-jacente - les tables de hachage, n'ont pas de notion de position. Contrairement à LinkedList ou Vector, la clé d'entrée est transformée en un «compartiment» où la valeur est stockée. Ces compartiments ne sont pas classés d'une manière qui a du sens en dehors de l'interface HashMap et, en tant que tels, les éléments que vous mettez dans le HashMap ne sont pas dans l'ordre dans le sens que vous attendez avec les autres structures de données
HashMap n'a pas de concept de position, il n'y a donc aucun moyen d'obtenir un objet par position. Les objets dans Maps sont définis et récupérés par clés.
Par défaut, java LinkedHasMap ne prend pas en charge l'obtention de valeur par position. Je suggère donc d'aller avec personnaliséIndexedLinkedHashMap
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);
}
}
Ensuite, vous pouvez utiliser cette LinkedHasMap personnalisée comme
IndexedLinkedHashMap<String,UserModel> indexedLinkedHashMap=new IndexedLinkedHashMap<>();
POUR ajouter des valeurs
indexedLinkedHashMap.add("key1",UserModel);
Pour obtenir la valeur par index
indexedLinkedHashMap.getItemByIndex(position);
Les HashMaps n'autorisent pas l'accès par position, il ne connaît que le code de hachage et il peut récupérer la valeur s'il peut calculer le code de hachage de la clé. Les TreeMaps ont une notion d'ordre. Les cartes Linkedhas conservent l'ordre dans lequel elles sont entrées sur la carte.
Vous pouvez essayer d'implémenter quelque chose comme ça, regardez:
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
J'espère que cela fonctionne pour vous.