web-dev-qa-db-fra.com

Java Classe qui implémente Map et conserve l'ordre d'insertion?

Je recherche une classe dans Java qui possède une association clé-valeur, mais sans utiliser de hachage. Voici ce que je fais actuellement:

  1. Ajouter des valeurs à un Hashtable.
  2. Obtenez un itérateur pour la Hashtable.entrySet().
  3. Parcourez toutes les valeurs et:
    1. Obtenez un Map.Entry pour l'itérateur.
    2. Créez un objet de type Module (une classe personnalisée) en fonction de la valeur.
    3. Ajoutez la classe à un JPanel.
  4. Montrer le panneau.

Le problème, c'est que je ne contrôle pas l'ordre dans lequel je récupère les valeurs, donc je ne peux pas afficher les valeurs dans un ordre donné (sans coder en dur l'ordre).

J'utiliserais un ArrayList ou Vector pour cela, mais plus tard dans le code, je dois récupérer l'objet Module pour une clé donnée, ce que je ne peux pas faire avec un ArrayList ou Vector.

Est-ce que quelqu'un connaît une classe Java libre/open-source capable de le faire ou un moyen de récupérer les valeurs d'un Hashtable en fonction du moment où elles ont été ajoutées?

Merci!

422
Shane

Je suggère un LinkedHashMap ou un TreeMap . Un LinkedHashMap conserve les clés dans l'ordre dans lequel elles ont été insérées, tandis qu'un TreeMap est conservé trié via un Comparator ou l'ordre naturel des éléments Comparable.

Comme il n'est pas nécessaire de garder les éléments triés, LinkedHashMap devrait être plus rapide dans la plupart des cas; TreeMap a O(log n) performance pour containsKey, get, put et remove, selon les Javadocs, alors que LinkedHashMap est O(1) pour chacun.

Si votre API attend uniquement un ordre de tri prévisible, par opposition à un ordre de tri spécifique, envisagez d'utiliser les interfaces implémentées par ces deux classes, NavigableMap ou SortedMap . Cela vous permettra de ne pas divulguer des implémentations spécifiques dans votre API et de basculer ensuite vers l'une de ces classes spécifiques ou vers une implémentation complètement différente.

675
Michael Myers

Si une carte immuable répond à vos besoins , il existe une bibliothèque appelée par Google appelée goyave (voir aussi questions sur la goyave) )

Guava fournit un ImmutableMap avec un ordre d'itération fiable spécifié par l'utilisateur. Cette ImmutableMap a O(1) performance pour containsKey, obtenez. Évidemment, mettre et supprimer ne sont pas pris en charge.

Les objets ImmutableMap sont construits à l'aide des méthodes de commodité statiques élégantes of () et copyOf () ou d'un Builder objet.

16
jvdneste

LinkedHashMap renverra les éléments dans l'ordre dans lequel ils ont été insérés lorsque vous parcourez le keySet (), entrySet () ou les valeurs () de la carte.

Map<String, String> map = new LinkedHashMap<String, String>();

map.put("id", "1");
map.put("name", "rohan");
map.put("age", "26");

for (Map.Entry<String, String> entry : map.entrySet()) {
    System.out.println(entry.getKey() + " = " + entry.getValue());
}

Ceci imprimera les éléments dans l'ordre dans lequel ils ont été mis sur la carte:

id = 1
name = rohan 
age = 26 
16
Praveen Kishor

Vous pouvez conserver un Map (pour une recherche rapide) et un List (pour un ordre), mais un LinkedHashMap peut être le plus simple. Vous pouvez également essayer un SortedMap par exemple. TreeMap, quel que soit l'ordre que vous spécifiez.

6
Peter Lawrey

Vous pouvez essayer mon carte d'arborescence liée .

1
Lawrence Dol

Je ne sais pas si c'est une source ouverte, mais après un peu de recherche sur Google, j'ai trouvé cette implémentation de Map en utilisant ArrayList . Il semble qu’il s’agisse d’une version de Java antérieure à la version 1.5, il est donc préférable de la généraliser, ce qui devrait être simple. Notez que cette implémentation a un accès O(N), mais cela ne devrait pas poser de problème si vous n'ajoutez pas des centaines de widgets à votre JPanel, ce qui ne devrait pas être le cas de toute façon.

1
jpalecek

Vous pouvez utiliser LinkedHashMap pour l'ordre d'insertion principal dans Map

Les points importants concernant la classe Java LinkedHashMap sont les suivants:

  1. Il ne contient que des éléments uniques.
  2. LinkedHashMap contient des valeurs basées sur la clé 3.Il peut avoir une clé NULL et plusieurs valeurs NULL. 4.Il est identique à HashMap qui conserve l’ordre d’insertion.

    public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> 
    

Mais si vous souhaitez trier les valeurs dans la carte à l'aide d'un objet défini par l'utilisateur ou d'une clé de type de données primitive, vous devez utiliser TreeMap . Pour plus d'informations, reportez-vous à ce lien

1
Pankaj Goyal

Chaque fois que j'ai besoin de maintenir l'ordre naturel des choses connues à l'avance, j'utilise un EnumMap

les clés seront des énumérations et vous pourrez les insérer dans l'ordre que vous voulez, mais si vous les répétez, elles se répètent dans l'ordre des énumérations (l'ordre naturel).

De même, lors de l'utilisation d'EnumMap, il ne devrait y avoir aucune collision qui puisse être plus efficace.

Je trouve vraiment qu'en utilisant EnumMap, le code est lisible et lisible. Voici un exemple

1
j2emanue