37

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

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行に次のようなエラーが表示されます。

互換性のないタイプ
見つかった:java.lang.Object
必須:MyClass.Key

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

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

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

4

5 に答える 5

42

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

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

可能であれば、「getData」を定義して、キャストが不要になるようにします。

于 2009-01-15T19:42:28.683 に答える
38

変化する:

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

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

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

于 2009-01-15T19:32:43.603 に答える
5

この簡単な例はJava フォーラムで見つけました。その構文は、私が探していた List の 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());
}

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

于 2011-04-19T21:40:19.783 に答える
5

キークラスを必要としないように、代わりに 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;
}
于 2009-01-15T19:39:10.983 に答える
3

モトリンの答えは正しいです。

メモが2つある...

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

  2. マーティンが提案したキャストは、チェックされていない警告を表示しますが、これは本当に安全ではないため、取り除くことはできません。

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

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

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

于 2009-01-15T19:38:57.397 に答える