Java映射混合类型

时间:2012-04-10 00:13:54

标签: java hashmap

我正在寻找一种创建映射到混合类型的HashMap的方法。

例如,以下内容适用于Python(请注意,Python dict类似于Java HashMap):

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

并且在访问d[x]时,将返回相应的类型(在此示例中为string,float,int)。

在Java中,我可以使用HashMap<String, Object>,但我真的无法立即告诉每个Object的类型。

所以相反,我现在要做的是创建一个包含对象的MixedType类,以及它的原始类型信息,以便我可以在以后转发它。例如:

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 个答案:

答案 0 :(得分:7)

正确的做法是m1.cls.cast(m1.val),但与普通Map<String, Object>相比,你几乎肯定不会获得任何收益。一种更简单的方法可以让您获得完全相同的类型安全性和完全相同的信息 - 也就是说,并不多 - 只需在您的getClass()值上使用Object方法地图。

这一切都不会达到你能够说String value = map.get("str")的目标 - 没有任何一个直接的演员会做到这一点。你可以做到

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

或类似的东西。

如果您在编译时知道其使用点的值类型,那么到目前为止最好的解决方案就是继续在使用点进行转换。一般来说,这样做配置的“理想”方式不是使用Map,而是构建一个在编译时知道其字段及其类型的自定义Configuration类,但是如果你想要使用Map,然后直接进行演员表演可能是你最好的选择。

答案 1 :(得分:3)

之前我已经实现了类似的东西。您可以使用泛型来协助。您想要的是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

VS

String str = (String)map.get("keyForIntProperty"); // run-time error only