密钥和值类型之间关系的对象映射

时间:2016-05-27 14:48:11

标签: java dictionary

在“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)第一个问题是,为了改进代码,可以替换:

    Map<FooKey<?>,Object> data;

通过以下方式:

    Map<FooKey<T>,T> data;

b)第二个问题是:某种方式可以使用单个枚举的可能键,而不是每个可能类型的值的一个枚举?类似的东西:

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

c)欢迎任何与此代码相关的其他建议。

感谢。

1 个答案:

答案 0 :(得分:1)

不幸的是,Java的类型系统不够复杂,无法表示地图的实际类型。为此,您需要提供一个类型等式,显示键和值类型是如何相关的,而Java没有这样的语法。

所以你能做到的最好就是像你在这里一样投入到T中。如果需要,您可以添加@SuppressWarnings("unchecked")以使警告消失。

如果需要,您可以抑制一行,如下所示:

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

从根本上说,Map<FooKey<T>, T>不能是您想要的类型,因为这会限制地图只包含单个类型的值T。