2010-01-12 5 views
18

Per quanto ho capito, sembra che non ci sia un modo diretto per ottenere uno Enumeration direttamente per le chiavi di un HashMap. Posso solo ottenere un keySet(). Da quello Set, posso ottenere uno Iterator ma uno Iterator sembra essere qualcosa di diverso da uno Enumeration.Ottieni un'enumerazione (per le chiavi) di una mappa (HashMap) in Java?

Qual è il modo migliore e più efficace per ottenere direttamente un Enumeration dalle chiavi di un HashMap?

Background: Io sono l'attuazione mia ResourceBundle (=>getKeys() Method), e devo fornire/implementare un metodo che restituisce l'enumerazione di tutte le chiavi. Ma la mia implementazione è basata su un HashMap quindi ho bisogno di capire in qualche modo come meglio convertire tra queste due tecniche "Iterator/Enumerator".

+3

C'è qualche motivo per cui è necessario enumerazioni al posto di iteratori? Javadoc di enumerazione consiglia di utilizzare invece Iterator. – lins314159

+1

beh, l'implementazione della classe I richiede un'enumerazione: http://java.sun.com/javase/6/docs/api/java/util/ResourceBundle.html#getKeys() (vedere il metodo getKey() lì L'unica cosa che potrei fare è implementarla completamente diversa e non usare affatto HashMap. Tuttavia sarei molto interessato ad apprendere quale sia il modo migliore e più performante per ottenere un'enumerazione per le chiavi di una mappa. Grazie! – tim

risposta

20

Apache commons-collections hanno un adattatore che rende disponibili Iterator per l'uso come un Enumeration. Dai un'occhiata a IteratorEnumeration.

adattatore per fare un'istanza Iterator sembrano essere un istanze enumerazione

Così, in breve di effettuare le seguenti:

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

In alternativa, se (per qualche motivo) don' t voglio includere commons-collections, puoi implementare questo adattatore tu stesso. E 'facile - basta fare un'implementazione di Enumeration, passare il Iterator in un costruttore, e ogni volta che hasMoreElements() e nextElement() sono chiamati, si chiama la hasNext() e next() sul sottostante Iterator.

Utilizzare questo se si è costretti a utilizzare Enumeration con un contratto API (come presumo che sia il caso). Altrimenti usa Iterator - è l'opzione consigliata.

+2

Google Collections supporta anche questo utilizzando 'Iterators.asEnumerator()': http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Iterators.html#asEnumeration(java.util .Iterator) –

+0

ciao Bozho. Grazie, è stato particolarmente interessante il tuo commento su come implementarlo da solo. Non mi sono reso conto fino ad ora di poterlo fare da solo. – tim

+0

+1 per la lezione. –

34

Penso che si può utilizzare il metodo di enumerazione da java.util.Collections classe per ottenere quello che vuoi.

la documentazione delle API del metodo Enumerate ha questo da dire:

pubblico enumerazione Enumeration statico (Collection c)
restituisce un'enumerazione sulla raccolta specificato. Ciò garantisce l'interoperabilità con le API legacy che richiedono un'enumerazione come input.

Ad esempio, il frammento di codice di seguito ottiene un'istanza di enumerazione dal keyset di 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()); 
} 

e conseguente dell'output sono:
uno
due
tre

+0

+1 Questo è il modo per andare fin quando inizi con la raccolta. Non è necessario scrivere il proprio adattatore per enumerare un set di chiavi. –

0

È possibile scrivere un adattatore per adattarsi a Enumerazione.

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(); 
     } 

    } 

E quindi è possibile utilizzare questa enumerazione personalizzati :)