37 Stimmen

Wie verwende ich eine foreach-Schleife in Java, um durch die Werte in einer HashMap zu iterieren?

Ich versuche, den folgenden Code zu kompilieren:

private String dataToString(){
    Map data = (HashMap) getData();
    String toString = "";
    for( MyClass.Key key: data.keySet() ){
        toString += key.toString() + ": " + data.get( key );
    return toString;
}

Ich erhalte einen Fehler in der Zeile des for-Loops, der besagt:

inkompatible Typen
gefunden: java.lang.Object
erwartet: MyClass.Key

Die getData() Methode gibt ein Object zurück (aber in diesem Fall hat das zurückgegebene Object die Struktur eines HashMaps). MyClass.Key ist ein enum, das ich für die Zwecke meiner Anwendung erstellt habe (in einer anderen Klassendatei - MyClass).

Als ich eine foreach-Schleife mit derselben Struktur in MyClass.java erstellt habe, bin ich auf dieses Problem nicht gestoßen.

Was mache ich falsch?

0 Stimmen

Es ist nicht notwendig, getData() in ein HashMap zu casten, wenn Sie es nur einem Map zuweisen. Werfen Sie es stattdessen in eine Map. Was ist, wenn getData() kein HashMap zurückgibt (wie beispielsweise ein TreeMap)?

0 Stimmen

Ich habe hier tatsächlich einige Informationen weggelassen ... getData() ist tatsächlich getData(String key), wobei key das gewünschte Objekt angibt, das ich erhalten möchte. Da ich also das Objekt kenne, das ich erhalte, weiß ich genau, in was ich es umwandeln sollte.

43voto

Paul Tomblin Punkte 172816

Eine etwas effizientere Möglichkeit, dies zu tun:

  Map data = (HashMap) getData(); 
  StringBuffer sb = new StringBuffer();
  for (Map.Entry entry : data.entrySet()) {
       sb.append(entry.getKey());
       sb.append(": ");
       sb.append(entry.getValue());
   }
   return sb.toString();

Wenn möglich, definieren Sie "getData" so, dass Sie den Cast nicht benötigen.

38voto

Craig P. Motlin Punkte 26028

Ändern:

Map data = (HashMap) getData();

zu

Map data = (HashMap) getData();

Das Problem ist, dass data.keySet() eine Collection zurückgibt, wenn data nur eine `Map` ist. Sobald Sie es generisch machen, wird `keySet()` eine `Collection` zurückgeben. Noch besser... iterieren Sie über das `entrySet()`, was eine `Collection` sein wird. Das vermeidet zusätzliche Hash-Lookups.

5voto

Richard Campbell Punkte 3570

Sie könnten stattdessen den Eintragssatz abrufen, um die erforderliche Schlüsselklasse zu vermeiden:

private String dataToString(){    
    Map data = (HashMap) getData();    
    String toString = "";    
    for( Map.Entry entry: data.entrySet() ) {        
        toString += entry.getKey() + ": " + entry.getValue();
    }    
    return toString;
}

5voto

dialex Punkte 2528

Ich habe dieses einfache Beispiel im Java-Forum gefunden. Seine Syntax ist der List's foreach sehr ähnlich, was ich gesucht habe.

import java.util.Map.Entry;
HashMap nameAndAges = new HashMap();
for (Entry entry : nameAndAges.entrySet()) {
        System.out.println("Name : " + entry.getKey() + " age " + entry.getValue());
}

[EDIT:] Ich habe es getestet und es funktioniert perfekt.

3voto

Peter Štibraný Punkte 31886

Antwort von Motlin ist korrekt.

Ich habe zwei Anmerkungen...

  1. Verwenden Sie nicht toString += ..., sondern verwenden Sie stattdessen StringBuilder und fügen Sie Daten hinzu.

  2. Das von Martin vorgeschlagene Casting wird Ihnen eine unbeaufsichtigte Warnung geben, von der Sie sich nicht befreien können, da es wirklich unsicher ist.

Ein weiterer Weg, ohne Warnung (und mit StringBuilder):

private String dataToString(){
    Map data = (Map) getData();
    StringBuilder toString = new StringBuilder();
    for (Object key: data.keySet()) {
        toString.append(key.toString());
        toString.append(": ");
        toString.append(data.get(key));
    }
    return toString.toString();
}

Dies funktioniert, weil die toString-Methode, die Sie für key aufrufen, in der Object-Klasse definiert ist, daher benötigen Sie überhaupt kein Casting.

Die Verwendung von entrySet ist sogar noch besser, da kein weiterer Lookup in der Map durchgeführt werden muss.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X