带有通配符的Java HashMap嵌套泛型

带有通配符的Java HashMap嵌套泛型,java,generics,hashmap,Java,Generics,Hashmap,我正在尝试制作一个hashmap值的hashmap,其中包含自定义类的不同子类的HashSet,如下所示: HashMap<String, Hashmap<String, HashSet<? extends AttackCard>>> superMap 进入超级地图后,我得到一个编译器错误: 以下是发生错误的代码: public class CardPool { private HashMap<String, HashMap<String,

我正在尝试制作一个hashmap值的hashmap,其中包含自定义类的不同子类的HashSet,如下所示:

HashMap<String, Hashmap<String, HashSet<? extends AttackCard>>> superMap
进入超级地图后,我得到一个编译器错误:

以下是发生错误的代码:

public class CardPool {

private HashMap<String, HashMap<String, HashSet<? extends AttackCard>>> attackPool =
    new HashMap<>();

private ArrayList<AuxiliaryCard> auxiliaryPool;

public CardPool() {
(line 24)this.attackPool.put("assassins", new AssassinPool().get());
/*  this.attackPool.put("fighters", new Fighter().getPool());
    this.attackPool.put("mages", new Mage().getPool());
    this.attackPool.put("marksmen", new Marksman().getPool());
    this.attackPool.put("supports", new Support().getPool());
    this.attackPool.put("tanks", new Tank().getPool());
*/  
    this.auxiliaryPool = new ArrayList<>(new AuxiliaryCard().getPool()); 
}
公共类卡池{

私有HashMap可能是一个协方差问题,您需要用
super
替换?
扩展

请参见

不要使用
哈希集如果处理不当,多级通配符有时会有点棘手。您应该首先学习如何读取多级通配符。然后您需要学习解释多级通配符中
扩展
超级
边界的含义。这些都是重要的概念在开始使用它们之前,你必须先学习,否则你可能很快就会发疯

解释多级通配符:

**多级通配符*应自上而下读取。首先读取最外层的类型。如果该类型再次是参数化类型,请深入该参数化类型的类型。理解具体参数化类型和通配符参数化类型的含义对理解如何使用它们起着关键作用。例如:

List<? extends Number> list;   // this is wildcard parameterized type
List<Number> list2;            // this is concrete parameterized type of non-generic type
List<List<? extends Number>> list3;  // this is *concrete paramterized type* of a *wildcard parameterized type*.
List<? extends List<Number>> list4;  // this is *wildcard parameterized type*
参考文献:


与单级通配符相关:


现在,这可能在你的脑海中清晰地描绘了一幅与泛型不变性相关的画面。
列表
不是
列表
,尽管
数字
的超类。
列表在这里作为文本而不是图像或图像链接发布异常堆栈跟踪。
是h的哈希映射ashmaps包含hashset
-->太深,您应该尝试编写一个自定义对象来处理top-map的值。第24行的编译错误:错误:找不到适合put的方法(String,HashMap>this.attackPool.put(“刺客”,new刺客池().get());方法HashMap.putp。(String,HashMapdon’t post images on SO,除非它确实是一个图像。用文本编写错误消息。在我尝试理解线程失败后,我只是继续使用super替换extends。我得到了相同的编译错误=/尽管更改
HashSet@RohitJain我建议所有声明在任何地方都
Set
。@Bohemian是的,很好。但我想你的声明应该是-
Map
。但是你不能在内部映射中放置
HashSet
。这就是我所说的。好吧,在我深入研究泛型类之前,你能确认如果我的映射不是两个级别,我就不会有任何问题吗?我的意思是,如果我想要HashMap,我可以添加刺客使用key1和Fighter到key2没有问题?@user2651804是的,您可以。我建议您在开始使用多级通配符之前先阅读一些泛型教程。我想说明一下,我正在初始化superMap,使其仅为“new Hashset()”。superMap中包含的实际hashMap来自其他类。例如:superMap.put(“key1”,新的OtherClass.getHashMap()最后,解决方案也有点令人失望。因为问题首先出现了,因为我希望在相应的子类中进行强类型检查。例如,刺客池应该只包含刺客的HashSet,而刺客池中的字段是HashMap,我不能将其作为HashMap@user2651804因为同样的原因,你不能n a
列表
到a
列表我花了很长很长时间盲目地盯着你的答案。你可能犯了逻辑错误吗?你是说列表3中唯一没有列出的东西是列表。但是在这里的评论中,你说列表也没有列入列表3?
private HashMap<String, HashSet<Assassin>> pool = new HashMap<>();

    public HashMap<String, HashSet<Assassin>> get() {
        return pool;
    }
compilation error at line 24: error: no suitable method found for `put(String, HashMap<String,HashSet<Assassin>>>` 
this.attackPool.put("assassins", new AssassinPool(). get()); 
method HashMap.putp.(String, HashMap<String,HashSet<? extends AttackCard>>>` is not applicable (actual argument `HashMap<String, HashSet<Assassin>>` cannot be converted to `HashMap<String, HashSet<? extends AttackCard>>` by method invocation conversion)
Map<String, Map<String, Set<? extends AttackCard>>> superMap
List<? extends Number> list;   // this is wildcard parameterized type
List<Number> list2;            // this is concrete parameterized type of non-generic type
List<List<? extends Number>> list3;  // this is *concrete paramterized type* of a *wildcard parameterized type*.
List<? extends List<Number>> list4;  // this is *wildcard parameterized type*
List<List<? extends Number>> list = new ArrayList<List<Integer>>();  // Wrong
list.add(new ArrayList<Float>());  // You can add an `ArrayList<Float>` right?
list4 = new ArrayList<Integer>(); 
list4 = new ArrayList<Double>(); 
HashMap<String, Hashmap<String, HashSet<? extends AttackCard>>> superMap;
HashMap<String, HashSet<? extends AttackCard>> map = new HashMap<String, HashSet<Assassin>>();   // This isn't valid
private HashMap<String, HashSet<? extends AttackCard>> pool = new HashMap<>();

public HashMap<String, HashSet<? extends AttackCard>> get() {
    return pool;
}
private HashMap<String, HashMap<String, ? extends HashSet<? extends AttackCard>>> superMap = new HashMap<>();
HashMap<String, ? extends HashSet<? extends AttackCard>> map = new HashMap<String, HashSet<Assassin>>();
Map<String, Map<String, ? extends Set<? extends AttackCard>>> superMap;