简体   繁体   English

如何声明具有可变泛型的地图?

[英]How to declare a map with variable generics?

I have a Map whose keys are of generic type Key<T> , and values are of type List<T> . 我有一个Map其键的类型为通用类型Key<T> ,值的类型为List<T> If the key is an instance of Key<String> , the value must be a List<String> , and the same rule applies to any other key-value pairs. 如果密钥是Key<String>的实例,则该值必须是List<String> ,并且相同的规则适用于任何其他键 - 值对。 I have tried the following but it does not compile: 我尝试了以下但它不编译:

Map<T, List<T>> map;

At present I have to declare it with "partial" generics: 目前我必须用“部分”泛型来声明它:

Map<Object, List> map;

I know this is bad but I currently have no better choice. 我知道这很糟糕,但我目前没有更好的选择。 Is it possible to use generics in this situation? 在这种情况下是否可以使用泛型?

UPDATE UPDATE

Maybe I didn't express my problem clearly. 也许我没有清楚地表达我的问题。 I want a map that is able to: 我想要一张能够:

map.put(new Key<String>(), new ArrayList<String>());
map.put(new Key<Integer>(), new ArrayList<Integer>());

And the following code should not compile: 并且以下代码不应该编译:

map.put(new Key<String>(), new ArrayList<Integer>());

The key and value should always have the same generic type while the generic type can be any, and obviously extending a map does not meet my requirement. 键和值应始终具有相同的泛型类型,而泛型类型可以是任何类型,显然扩展映射不符合我的要求。

I'm not aware of any existing library that does precisely this but it is not too hard to implement yourself. 我不知道任何现有的库正是如此,但实现起来并不难。 I've done something similar a few times in the past. 我过去做过几次类似的事情。 You cannot use the standard Map interface but you can use a hash map inside to implement your class. 您不能使用标准的Map接口,但可以在里面使用哈希映射来实现您的类。 To start, it might look something like this: 首先,它可能看起来像这样:

public class KeyMap {
  public static class Key<T> { }

  private final HashMap<Object,List<?>> values = new HashMap<Object,List<?>>();

  public <T> void put(Key<T> k, List<T> v) {
    values.put(k, v);
  }

  public <T> List<T> get(Key<T> k) {
    return (List<T>)values.get(k);
  }

  public static void main(String[] args) {
    KeyMap a = new KeyMap();
    a.put(new Key<String>(), new ArrayList<String>());
    a.get(new Key<Integer>());
  }
}

This is what you want: 这就是你想要的:

public class Test<T> extends HashMap<T, List<T>>
{
}

If you don't want a HashMap as the super class then change it to whatever concrete class you want. 如果您不希望将HashMap作为超类,则将其更改为您想要的任何具体类。

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

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