2010-01-12 3 views
18

Pour autant que je comprenne cela, il semble qu'il n'y ait pas un moyen direct d'obtenir un Enumeration directement pour les clés d'un HashMap. Je peux seulement obtenir un keySet(). De ce Set, je peux obtenir un Iterator mais un Iterator semble être quelque chose de différent d'un Enumeration.Obtenir une énumération (pour les clés) d'une carte (HashMap) en Java?

Quel est le moyen le meilleur et le plus performant pour obtenir directement un Enumeration à partir des touches d'un HashMap? Contexte: J'applique ma propre méthode ResourceBundle (=>getKeys()), et je dois fournir/implémenter une méthode qui renvoie l'énumération de toutes les clés. Mais ma mise en œuvre est basée sur un HashMap donc je dois trouver comment convertir au mieux ces deux techniques "Iterator/Enumerator".

+3

Y at-il des raisons pour lesquelles vous avez besoin énumérations au lieu de itérateurs? Javadoc de l'énumération vous recommande d'utiliser Iterator à la place. – lins314159

+1

bien, la classe que je suis en train de mettre en œuvre nécessite une énumération: http://java.sun.com/javase/6/docs/api/java/util/ResourceBundle.html#getKeys() (voir la méthode getKey() ici La seule chose que je pourrais faire est de l'implémenter complètement différemment et de ne pas utiliser HashMap du tout. Néanmoins, je serais très intéressé à apprendre quelle est la meilleure et la plus performante façon d'obtenir une énumération pour les clés d'une carte. Merci! – tim

Répondre

20

Apache commons-collections avoir un adaptateur qui rend le Iterator disponible pour une utilisation comme un Enumeration. Jetez un oeil à IteratorEnumeration.

Adaptateur pour faire une instance Iterator semble être un cas Enumeration

Donc, en bref, vous procédez comme suit:

Enumeration enumeration = new IteratorEnumeration(hashMap.keySet().iterator()); 

Alternativement, si vous (pour une raison quelconque) n » Si vous voulez inclure des collections-communes, vous pouvez implémenter cet adaptateur vous-même. Il est facile - il suffit de faire une implémentation de Enumeration, passez le Iterator dans un constructeur, et chaque fois que hasMoreElements() et nextElement() sont appelés, vous appelez hasNext() et next() sur le Iterator sous-jacent.

Utilisez ceci si vous êtes obligé d'utiliser Enumeration par un contrat API (comme je suppose que le cas est). Sinon, utilisez Iterator - c'est l'option recommandée.

+2

Google Collections prend également en charge cette utilisation de 'Iterators.asEnumerator()': http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Iterators.html#asEnumeration(java.util .Iterator) –

+0

bonjour Bozho. Merci, particulièrement intéressant était votre commentaire comment mettre en œuvre cela par moi-même. Je n'avais pas réalisé jusqu'à présent que je pouvais le faire tout seul. – tim

+0

+1 pour la leçon. –

34

Je pense que vous pouvez utiliser la méthode énumération de java.util.Collections classe pour obtenir ce que vous voulez.

L'API doc de la Énumérer méthode a ceci à dire:

énumération Enumeration public static (Collection c)
Retourne une énumération sur la collection spécifiée. Cela permet l'interopérabilité avec les API héritées qui nécessitent une énumération en entrée.

Par exemple, l'extrait de code ci-dessous obtient une instance de Énumération du keyset de HashMap

final Map <String,Integer> test = new HashMap<String,Integer>(); 
test.put("one",1); 
test.put("two",2); 
test.put("three",3); 
final Enumeration<String> strEnum = Collections.enumeration(test.keySet()); 
while(strEnum.hasMoreElements()) { 
    System.out.println(strEnum.nextElement()); 
} 

et résultant de la sortie est:
un
deux
trois

+0

+1 C'est le chemin à parcourir tant que vous commencez avec la collection. Pas besoin d'écrire votre propre adaptateur pour énumérer un jeu de clés. –

0

Vous pouvez écrire un adaptateur pour l'adapter à l'énumération.

public class MyEnumeration implements Enumeration { 

     private Iterator iterator; 

     public MyEnumeration(Iterator iterator){ 
      this.iterator = iterator; 
     } 


     public MyEnumeration(Map map) { 
      iterator = map.keySet().iterator(); 
     } 


     @Override 
     public boolean hasMoreElements() { 
      return iterator.hasNext(); 
     } 


     @Override 
     public Object nextElement() { 
      return iterator.next(); 
     } 

    } 

Et vous pouvez utiliser cette énumération personnalisée :)

Questions connexes