2012-04-10 138 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