Javaのforeachループを使用してHashMapの値をループするにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/448122

  •  19-08-2019
  •  | 
  •  

質問

次のコードをコンパイルしようとしています:

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

for行にエラーが表示されます:

incompatible types
found : java.lang.Object
required: MyClass.Key

getData()メソッドはObjectを返します(ただし、この場合、返されるHashMapMyClass.Key構造を持ちます)。 MyClassは、アプリケーションの目的で作成した列挙型です(別のクラスファイル-MyClass.java)。

<=>で同じ構造のforeachループを作成したとき、この問題は発生しませんでした。

何が間違っているのですか?

役に立ちましたか?

解決

これを行うためのもう少し効率的な方法:

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

可能な限り、<!> quot; getData <!> quot;を定義します。キャストは必要ありません。

他のヒント

変更:

Map data = (HashMap<MyClass.Key, String>) getData();

to

Map<MyClass.Key, String> data = (HashMap<MyClass.Key, String>) getData();

問題は、データが単なるdata.keySet()の場合、Collection<Object>Mapを返すことです。ジェネリックにすると、keySet()Collection<MyClass.Key>を返します。さらに良い... entrySet()を反復処理します。これはCollection<MyClass.Key, String>になります。余分なハッシュルックアップを回避します。

javaフォーラムでこの簡単な例を見つけました。 構文は、リストのforeachと非常に似ています。これは私が探していたものです。

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

[編集:]私はそれをテストし、完全に動作します。

代わりにentrySetを取得して、キークラスが不要になるようにすることができます。

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

Motlinの答えは正しいです。

メモが2つあります...

  1. toString += ...は使用せず、代わりにStringBuilderを使用してデータを追加します。

  2. Martinが提案したキャストは未確認の警告を表示しますが、本当に安全ではないため、取り除くことはできません。

別の方法、警告なし(および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();
}

これは機能します。これは、keyで呼び出すtoStringメソッドがObjectクラスで定義されているため、キャストする必要がないためです。

マップで別のルックアップを行う必要がないため、entrySetを使用するとさらに良い方法になります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top