2010-07-01 17 views

Odpowiedz

20

Tak - na przykład:

Map<String, String> map = new HashMap<String, String>(); 
// add entries to the map here 

for (Map.Entry<String, String> entry : map.entrySet()) { 
    String k = entry.getKey(); 
    String v = entry.getValue(); 
    System.out.printf("%s %s\n", k, v); 
} 
+8

Porównanie tego z wersją Pythona przypomina mi, dlaczego zrezygnowałem z Jawy kilka lat temu. –

3
Set<Map.Entry> set = d.entrySet(); 
for(Map.Entry i : set){ 
    System.out.println(i.getKey().toString() + i.getValue().toString); 
} 

Coś takiego ...

1

W Javie można zrobić to samo jak poniżej.

HashMap<String, String> h = new HashMap<String, String>(); 
    h.put("1","one"); 
    h.put("2","two"); 
    h.put("3","three"); 

    for(String key:h.keySet()){ 
     System.out.println("Key: "+ key + " Value: " + h.get(key)); 
    } 
+0

Dlaczego upadek? – bragboy

+0

Nie zrobiłem tego, ale to podejście jest mniej wydajne niż iterowanie nad zestawem pozycji. 'Get()' ma dodatkową cenę na każdej iteracji. To nie jest "właściwy" sposób na przeglądanie mapy. Mogę sobie wyobrazić, że ktoś z tego powodu przegrał, jak dobry jest twój zamiar. – BalusC

+2

@BalusC - tak, ale tworzenie iteratora MapEntrySet jest (najprawdopodobniej) droższe niż tworzenie iteratora zestawu ... Wątpię, że jest to problem z wydajnością, a nawet gdyby to było mniej wydajne, nigdy bym nigdy. ** Spróbuj rozwiązać problemy z wydajnością, * optymalizując * pętle w ten sposób. (+1 ode mnie, BTW). –

6

Jak widać w odpowiedziach, istnieją zasadniczo dwa sposoby iteracyjne nad Map (załóżmy Map<String, String> w tych przykładach).

  1. iteracyjnego Map#entrySet():

    for (Entry<String, String> entry : map.entrySet()) { 
        System.out.println(entry.getKey() + "=" + entry.getValue()); 
    } 
    
  2. iteracyjnego Map#keySet() a następnie użyć Map#get() uzyskać wartość dla każdego klucza:

    for (String key : map.keySet()) { 
        System.out.println(key + "=" + map.get(key)); 
    } 
    

Drugi to może więcej czytelny, ale ma niepotrzebnie wysokie koszty związane z wydajnością get() na każdej iteracji. Można argumentować, że tworzenie iteratora zestawu kluczy jest tańsze, ponieważ nie musi brać pod uwagę wartości. Ale uwierz lub nie, keySet().iterator() tworzy i używa iteratora jako jako entrySet().iterator(). Jedyna różnica polega na tym, że w przypadku wywołania keySet() wywołanie iteratora zwraca it.next().getKey() zamiast it.next().

AbstractMap#keySet()'s javadoc dowodzi to:

Metoda iterator podklasy wraca do "obiekt otoki" nad tą mapą w entrySet() iteracyjnej.

Dowodzi tego również kod źródłowy AbstractMap. Oto wyciąg z keySet() metodą (gdzieś w okolicach linii 300 w Javie 1.6):

public Iterator<K> iterator() { 
    return new Iterator<K>() { 
     private Iterator<Entry<K,V>> i = entrySet().iterator(); // <----- 

     public boolean hasNext() { 
      return i.hasNext(); 
     } 

     public K next() { 
      return i.next().getKey(); // <----- 
     } 

     public void remove() { 
      i.remove(); 
     } 
    }; 
} 

Zauważ, że czytelność powinna mieć pierwszeństwo przed przedwczesnym optymalizacji, ale ważne jest, aby mieć to na uwadze.