2013-03-14 16 views
15

Próbowałem iterować nad hashmap w Javie, co powinno być dość łatwe do zrobienia. Jednak poniższy kod daje mi pewne problemy:Iterator nad HashMap w Javie

HashMap hm = new HashMap(); 

hm.put(0, "zero"); 
hm.put(1, "one"); 

Iterator iter = (Iterator) hm.keySet().iterator(); 

while(iter.hasNext()) { 

    Map.Entry entry = (Map.Entry) iter.next(); 
    System.out.println(entry.getKey() + " - " + entry.getValue()); 

} 

Po pierwsze, potrzebne do oddania Iterator na hm.keySet() iterator(), bo inaczej to powiedział „Niezgodność typów. Nie można przekonwertować z java.util. Iterator do Iteratora ". Ale wtedy otrzymuję "Metoda hasNext() jest niezdefiniowana dla Iteratora typu" i "Metoda hasNext() jest niezdefiniowana dla Iteratora typu".

+5

Wygląda na to, że zaimportowano niewłaściwą klasę "Iterator". Będziesz chciał zaimportować 'java.util.Iterator'. – Vulcan

+2

Musisz pętli nad entrySet() nie keySet(), jeśli chcesz wprowadzić, a nie klucze. –

Odpowiedz

39

możemy zobaczyć swój blok import? ponieważ wydaje się, że zaimportowałeś niewłaściwą klasę Iterator.

Jeden należy użyć jest java.util.Iterator

Aby upewnić się, spróbuj:

java.util.Iterator iter = hm.keySet().iterator(); 

Osobiście proponuję następujące:

Oświadczenie Mapa stosując Generics i deklaracji za pomocą interfejs Map<K,V> i tworzenie instancji przy użyciu pożądane realizacja HashMap<K,V>

Map<Integer, String> hm = new HashMap<>(); 

i na pętli:

for (Integer key : hm.keySet()) { 
    System.out.println("Key = " + key + " - " + hm.get(key)); 
} 

UPDATE 3/5/2015

okazało się, że iteracja nad zestawem wpis zostanie lepszą wydajność mądry:

for (Map.Entry<Integer, String> entry : hm.entrySet()) { 
    Integer key = entry.getKey(); 
    String value = entry.getValue(); 

} 

UPDATE 10/3/2017

Dla Java8 i strumieni, rozwiązanie będzie

hm.entrySet().stream().forEach(item -> 
        System.out.println(item.getKey() + ": " + item.getValue()) 
      ); 
+2

Twoje rozwiązanie aktualizacji jest także moim ulubionym ;-) – zypro

6

Należy naprawdę użyć rodzajowych i wzmocnione dla pętli do tego:

Map<Integer, String> hm = new HashMap<>(); 
hm.put(0, "zero"); 
hm.put(1, "one"); 

for (Integer key : hm.keySet()) { 
    System.out.println(key); 
    System.out.println(hm.get(key)); 
} 

http://ideone.com/sx3F0K

Albo wersja entrySet():

Map<Integer, String> hm = new HashMap<>(); 
hm.put(0, "zero"); 
hm.put(1, "one"); 

for (Map.Entry<Integer, String> e : hm.entrySet()) { 
    System.out.println(e.getKey()); 
    System.out.println(e.getValue()); 
} 
+0

czy możesz określić, jakie są różnice między tymi dwoma podejściami? –

+0

@ HussainAkhtarWahid'Ghouri 'Praktycznie mówiąc żaden - dlatego nie wspomniałem o żadnym. Drugi może być nieznacznie szybszy, ponieważ unikasz wyszukiwania hashów w każdej iteracji. (Lub może nie być). – millimoose

+0

Co zrobić, jeśli potrzebuje zmodyfikować swoją mapę? wystąpi w przypadku wyjątku modyfikacji współbieżnej. – Eddnav

0

najczystszy sposób to nie (bezpośrednio) używać iterator na wszystkich:

  • typu twoja mapa z generics
  • użyć pętli foreach do iteracji nad wpisami:

Jak to:

Map<Integer, String> hm = new HashMap<Integer, String>(); 

hm.put(0, "zero"); 
hm.put(1, "one"); 

for (Map.Entry<Integer, String> entry : hm.entrySet()) { 
    // do something with the entry 
    System.out.println(entry.getKey() + " - " + entry.getValue()); 
    // the getters are typed: 
    Integer key = entry.getKey(); 
    String value = entry.getValue(); 
} 

To jest bardziej wydajne niż Iterowanie nad klucze, ponieważ można uniknąć n wzywa do get(key).

+0

zmienić JM na hm. myślę ... popraw mnie jeśli się mylę :) – Neo

+0

@neo thx. To musiała być automatyczna poprawka dla iPhone'a: ​​/ – Bohemian

0

kilka problemów:

  • Prawdopodobnie nie używać odpowiedniego klasę iteracyjnej. Jak powiedzieli inni, użyj import java.util.Iterator
  • Jeśli chcesz użyć Map.Entry entry = (Map.Entry) iter.next();, musisz użyć hm.entrySet().iterator(), a nie hm.keySet().iterator(). Albo wykonaj iterację na klawiszach, albo na wpisach.
0
Map<String, Car> carMap = new HashMap<String, Car>(16, (float) 0.75); 

// nie ma iterator na mapach, ale istnieją sposoby, aby to zrobić.

 Set<String> keys = carMap.keySet(); // returns a set containing all the keys 
     for(String c : keys) 
     { 

      System.out.println(c); 
     } 

     Collection<Car> values = carMap.values(); // returns a Collection with all the objects 
     for(Car c : values) 
     { 
      System.out.println(c.getDiscription()); 
     } 
     /*keySet and the values methods serve as “views” into the Map. 
      The elements in the set and collection are merely references to the entries in the map, 
      so any changes made to the elements in the set or collection are reflected in the map, and vice versa.*/ 

     ////////////////////////////////////////////////////////// 
     /*The entrySet method returns a Set of Map.Entry objects. 
      Entry is an inner interface in the Map interface. 
      Two of the methods specified by Map.Entry are getKey and getValue. 
      The getKey method returns the key and getValue returns the value.*/ 

     Set<Map.Entry<String, Car>> cars = carMap.entrySet(); 
     for(Map.Entry<String, Car> e : cars) 
     { 
      System.out.println("Keys = " + e.getKey()); 
      System.out.println("Values = " + e.getValue().getDiscription() + "\n"); 

     } 
3

Z Java 8:

hm.forEach((k, v) -> { 
    System.out.println("Key = " + k + " - " + v); 
}); 
+0

jest to zbyt łatwe dzięki java 8 – AndroidLover

0

Iterator poprzez keySet daje klucze. Powinieneś użyć entrySet, jeśli chcesz powtórzyć wpisy.

HashMap hm = new HashMap(); 

hm.put(0, "zero"); 
hm.put(1, "one"); 

Iterator iter = (Iterator) hm.entrySet().iterator(); 

while(iter.hasNext()) { 

    Map.Entry entry = (Map.Entry) iter.next(); 
    System.out.println(entry.getKey() + " - " + entry.getValue()); 

}