2012-04-10 152 views
5

我正在尋找一種方法來創建映射到混合類型的HashMap。Java映射混合類型

例如,下面將在Python工作(請注意,一個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>,但我沒有辦法立即告訴每個對象是什麼類型。

因此,我現在試圖做的是創建一個持有對象的類,但也包含其原始類型信息,以便稍後可以向下轉發它。例如:

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

請注意,這是我試圖做:-) 因爲它目前還沒有編制抱怨m1 cannot be resolved to a type

所以我的問題是,我該如何解決這個問題?其他可以達到同樣目標的方法也會受到歡迎,但請不要回答告訴我這樣做會限制編譯器的類型檢查能力 - 我知道這一點並且可以。

在此先感謝。

+2

我可以問一下:你會如何處理一次檢索到的對象?我覺得通常有更好的方法來設計這個,以避免必須施放。 – 2012-04-10 00:17:13

+1

即使您的類型信息存儲在您的普通「對象」中,您在投出後又如何知道該怎麼做? – 2012-04-10 00:19:50

+0

當然,我將使用HashMap作爲「配置」類型對象,其中用戶將指定某些配置設置,並將其解析並放入此映射。在程序中的某些地方,我將檢查是否設置了某個配置選項,如果是,則使用它,如果不使用默認值。需要混合類型的原因是一些配置選項將是字符串,其他浮點數,其他整數等。 – jedwards 2012-04-10 00:20:18

回答

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 2012-04-10 00:33:59

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