web-dev-qa-db-fra.com

Est-il possible d'obtenir un élément de HashMap par sa position?

Comment récupérer un élément de HashMap par sa position, est-ce possible?

91
Eugene

HashMaps ne conserve pas l'ordre:

Cette classe ne fait aucune garantie quant à l'ordre de la carte; en particulier, cela ne garantit pas que l'ordre restera constant dans le temps.

Jetez un œil à LinkedHashMap , qui garantit un ordre d'itération prévisible.

87
Wayne Burkett

Utilisez un LinkedHashMap et lorsque vous avez besoin de récupérer par position, convertissez les valeurs en 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);
100
Kulnor

Si vous souhaitez conserver l'ordre dans lequel vous avez ajouté les éléments à la carte, utilisez LinkedHashMap plutôt que simplement 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 ] );
}
43
Syd Lambert

Si, pour une raison quelconque, vous devez vous en tenir à hashMap, vous pouvez convertir le jeu de clés en un tableau et indexer les clés du tableau pour obtenir les valeurs dans la carte, comme suit:

Object[] keys = map.keySet().toArray();

Vous pouvez alors accéder à la carte comme:

map.get(keys[i]);
16
artiethenoble

Utilisez LinkedHashMap :

Table de hachage et implémentation de la liste chaînée de l'interface Map, avec un ordre d'itération prévisible. Cette implémentation diffère de HashMap en ce qu'elle maintient une liste doublement chaînée traversant toutes ses entrées.

12
ilalex

Utilisez LinkedHashMap et utilisez cette fonction.

private LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();

Définir comme ça 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.

6
Jeff Lee

Une autre méthode de travail consiste à transformer les valeurs de la carte en tableau, puis à récupérer un élément à l’index. Le test de 100 000 éléments par recherche d'index dans LinkedHashMap de 100 000 objets à l'aide des 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 élément par index à partir de LinkedHashMap semble être une opération assez lourde.

3
user3738243

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 "seau" dans lequel la valeur est stockée. Ces compartiments ne sont pas ordonnés de manière logique en dehors de l'interface HashMap et, en tant que tels, les éléments que vous avez insérés dans HashMap ne sont pas en ordre dans le sens que vous pouvez attendre avec les autres structures de données.

2
dfb

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 des clés.

2
Robby Pond

Je suppose que par "position" vous faites référence à l'ordre dans lequel vous avez inséré les éléments dans la carte de hachage. Dans ce cas, vous souhaitez utiliser un LinkedHashMap. LinkedHashMap n'offre cependant pas de méthode d'accès. 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;
}
2
homebrew

vous pouvez utiliser le code ci-dessous pour obtenir la clé: String [] keys = (String[]) item.keySet().toArray(new String[0]);

et obtenez un objet ou une liste à insérer dans HashMap avec la clé de cet élément, comme ceci: item.get(keys[position]);

1
mahsa k

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é. TreeMaps ont une notion de commande. Les cartes Linkedhas préservent l'ordre dans lequel elles sont entrées dans la carte.

1
fastcodejava

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.

0