简体   繁体   English

具有键和值类型之间关系的对象映射

[英]Map of objects with relation between key and type of values

Following class "Foo" fulfills what is expected, a map of objects with "some control" about the relation between keys and type of the values.跟随类“Foo”满足预期,对象映射具有关于键和值类型之间的关系的“一些控制”。

import java.util.Map;

public class Foo {

    interface FooKey<T> {}

    enum IntFooKey implements FooKey<Integer> {
        Int1,
        Int2
    }

    enum StringFooKey implements FooKey<String> {
        S1,
        S2
    }


    Map<FooKey<?>,Object> data;

    public <T> T get( FooKey<T> k ) {
        return (T)data.get(k); // ugly warning
    }

    public <T> void put( FooKey<T> k, T v ) {
        data.put(k,v);
    }

    public void test() {
        Integer x = 1;   
        put( IntFooKey.Int1, x );
        x = get( IntFooKey.Int1 );

        String s = null;
        put( IntFooKey.Int2, s );  // COMPILATION ERROR, OK
        s = get( IntFooKey.Int2 );  // COMPILATION ERROR, OK
    }
}

a) the first question is, in order to improve the code, it is possible to replace: a) 第一个问题是,为了改进代码,可以替换:

    Map<FooKey<?>,Object> data;

by something like:通过类似的东西:

    Map<FooKey<T>,T> data;

b) the second question is: some way to have a single enum of possible keys, instead of one enum for each possible type of the value? b)第二个问题是:某种方法可以有一个单一的可能键的枚举,而不是每个可能的值类型的一个枚举? Something like:就像是:

enum FooKeys {
   Int1<Integer>,
   Int2<Integer>,
   S1<String>,
   S2<String>
}

c) Any other suggestion related to this code is also welcome. c) 也欢迎与此代码相关的任何其他建议。

Thanks.谢谢。

Unfortunately, Java's type system is not sophisticated enough to represent the actual type of your map.不幸的是,Java 的类型系统不够复杂,无法表示地图的实际类型。 To do that you would need to provide a type equation showing how the key and value types were related, and Java has no such syntax.要做到这一点,您需要提供一个类型方程来显示键和值类型是如何关联的,而 Java 没有这样的语法。

So the best you can do is cast to T like you're doing here.所以你能做的最好的事情就是像你在这里做的那样转换为 T 。 You can add a @SuppressWarnings("unchecked") to make the warning go away if you want.如果需要,您可以添加@SuppressWarnings("unchecked")以使警告消失。

You can suppress a single line if you want, like this:如果需要,您可以抑制单行,如下所示:

public <T> T get(FooKey<T> k)  {
    @SuppressWarnings("unchecked")
    T value = (T) data.get(k);
    return value;
}

Fundamentally, Map<FooKey<T>, T> cannot be the type you want, since that would constrain the map to only contain values of a single type, T.从根本上说, Map<FooKey<T>, T>不能是您想要的类型,因为这会限制映射仅包含单一类型 T 的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM