2012-04-10 6 views
5

混合型にマップするHashMapを作成する方法を探しています。Javaマッピングの混合型

たとえば、以下は、パイソン(Pythonのdictは、Java HashMapに類似していることに注意)で動作しますが:

d = dict() 
d["str"] = "This is a string" 
d["flt"] = 1.23 
d["int"] = 5 

d[x]にアクセスするときに、適切なタイプ(文字列、フロート、返されますこの例ではint)。

Javaでは、私はHashMap<String, Object>と一緒に行くことができましたが、どのオブジェクトがどのタイプであるかをすぐに知る方法はありません。

代わりに、私は現在オブジェクトを保持するMixedTypeクラスを作成するだけでなく、元のタイプ情報も作成して、後でダウンキャストできるようにしようとしています。例:これは私がはそれが現在そのm1 cannot be resolved to a typeを訴えてコンパイルしていないよう :-)行うにをしようとしているものであること

public class MixedMap 
    public static class MixedType 
    { 
     public Class<?> cls; 
     public Object val; 

     public MixedType(Class<?> c, Object v) 
     { 
      this.cls = c; 
      this.val = v; 
     } 
    } 

    public static void main(String args[]) 
    { 
     MixedType m1 = new MixedType(String.class, "This is a String"); 
     System.out.println((m1.cls)m1.val); 
    } 
} 

注意。

私の質問は、どうすれば修正できますか?同じ目標を達成するための他の方法も歓迎されるでしょうが、コンパイラの型チェック能力が制限されていると私には言い聞かせてください。私はそれを知っています。

ありがとうございます。

+2

私はちょうど質問することができます:一度取得したオブジェクトで何をしますか?私は通常、キャストすることを避けるためにこれを設計するより良い方法があるように感じます。 –

+1

普通のオブジェクトに情報が格納されていても、キャストした後に何をすべきかをどのように知っていますか? –

+0

確かに、HashMapを "設定"タイプのオブジェクトとして使用します。このオブジェクトでは、解析してこのマップに入れる特定の設定を指定します。プログラムの特定の時点で、特定の構成オプションが設定されているかどうかを確認し、使用する場合はデフォルトを使用します。混合型の必要性の理由は、いくつかの設定オプションが文字列、その他の浮動小数点数、他の整数などです。 – jedwards

答えて

6

適切なことはm1.cls.cast(m1.val)ですが、普通のMap<String, Object>と比べてほとんど確実に何も得られません。型の安全性とまったく同じ情報、正確には同じくらいの情報を得るための簡単なアプローチは、マップ内のObject値のgetClass()メソッドを使用することです。

これはどれも、String value = map.get("str")と言うことができるというあなたの目標を達成するものではありません。あなたはそうすることができます

Object value = map.get("str"); 
if (value instanceof String) { 
    // do stringy things 
} 

またはそれらの行に沿って何か。

コンパイル時に使用ポイントの値の型がわかっている場合、最も良い解決策は、使用ポイントでキャストを実行することです。一般的にこのような設定を行う「理想的な」方法は、Mapを使用するのではなく、コンパイル時にそのフィールドとその型を知っているカスタマイズされたConfigurationクラスを構築することですが、Mapを使用する場合はおそらくあなたの最良の賭けです。

+0

多くの代替ソリューションをありがとう! – jedwards

1

私はこれまでと同様のものを実装しました。ジェネリックを使って支援することができます。あなたが望むのはMixedKeyで、MixedMapのキーとして使用できます。これらの線に沿ったもの:

public class MixedKey<T> { 
    public final Class<T> cls; 
    public final String key; 

    public MixedKey(T cls, String key) { 
     this.key = key; 
     this.cls = cls; 
    } 

    // also implement equals and hashcode 
} 
public class MixedMap extends HashMap<MixedKey<?>,Object> { 
    public <T> T putMixed(MixedKey<T> key, T value) { 
     return key.cls.cast(put(key, value)); 
    } 

    public <T> T getMixed(MixedKey<T> key) { 
     return key.cls.cast(get(key)); 
    } 
} 

このような何かをやってのいいところは、あなたが誤って間違ったタイプを使用している場合、それは、あなたが直接鋳造して得られない何かをコンパイル時にエラーを与えるです:

MixedKey<Integer> keyForIntProperty 
    = new MixedKey<Integer>(Integer.class, "keyForIntProperty"); 

// ... 

String str = mixedMap.getMixed(keyForIntProperty); // compile-time error 

と対

String str = (String)map.get("keyForIntProperty"); // run-time error only 
関連する問題