7

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

例如,以下将在 Python 中工作(注意 Pythondict类似于 Java HashMap):

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

并且在访问时d[x],将返回适当的类型(本例中为字符串、浮点数、整数)。

在 Java 中,我可以使用 a 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

所以我的问题是,我该如何解决这个问题?实现相同目标的其他方法将受到欢迎,但请不要回答告诉我这限制了编译器的类型检查能力——我知道并且可以接受。

提前致谢。

4

2 回答 2

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
}

或类似的规定。

如果您在编译时知道值的使用点的类型,那么到目前为止最好的解决方案就是继续在使用点进行强制转换。像这样进行配置的“理想”方法通常不是使用 a Map,而是构建一个Configuration在编译时知道其字段及其类型的自定义类,但如果你想使用 a Map,那么直接进行强制转换是可能是你最好的选择。

于 2012-04-10T00:17:07.617 回答
4

我之前已经实现了类似的东西。您可以使用泛型来提供帮助。你想要的是一个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
于 2012-04-10T02:23:43.983 回答