- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试制作一个包含自定义类的不同子类的哈希集的hashmap值的hashmap,如下所示:
HashMap<String, Hashmap<String, HashSet<? extends AttackCard>>> superMap
AttackCard
具有子类,例如:
Mage
,
Assassin
和
Fighter
。 superMap中的每个HashMap将仅具有包含
AttackCard
的单个子类的HashSet。
HashMap<String, HashSet<Assassin>>
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());
}
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)
最佳答案
如果处理不当,多级通配符有时可能会有些棘手。您首先应该学习如何读取多级通配符。然后,您将需要学习解释多级通配符中extends
和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*
List<? extends Number>
的元素都可以放在外部列表中:
List<Number>
-是List<Integer>
-是List<Double>
-是List<String>
-无 List<List<? extends Number>> list = new ArrayList<List<Integer>>(); // Wrong
list.add(new ArrayList<Float>()); // You can add an `ArrayList<Float>` right?
ArrayList<Float>
添加到了一个本应仅包含
List<Integer>
的集合中。这肯定会在运行时给您带来麻烦。这就是为什么不允许这样做的原因,并且编译器仅在编译时才禁止这样做。
List
的所有实例化,其类型参数是
List<Number>
的子类。因此,以下分配对此类列表有效:
list4 = new ArrayList<Integer>();
list4 = new ArrayList<Double>();
Collection<Pair<String,Object>>
, a Collection<Pair<String,?>>
and a Collection<? extends Pair<String,?>>
? List<Number>
不是
List<Double>
,尽管
Number
是
Double
的父类(super class)。同样,即使
List<List<? extends Number>>
是
List<List<Integer>>
的父类(super class),但
List<? extends Number>
也不是
List<Integer>
。
HashMap<String, Hashmap<String, HashSet<? extends AttackCard>>> superMap;
List<List<List<? extends Number>>>
,与
List<List<? extends Number>>
不同。
superMap
的所有元素类型是什么?当然,您不能在
HashMap<String, HashSet<Assassin>>
中添加
superMap
。为什么?因为我们不能做这样的事情:
HashMap<String, HashSet<? extends AttackCard>> map = new HashMap<String, HashSet<Assassin>>(); // This isn't valid
HashMap<String, HashSet<? extends AttackCard>>
分配给
map
,因此只能将该类型的 map 作为
superMap
中的值。
Assassin
类(我想是)中的最后一部分代码修改为:
private HashMap<String, HashSet<? extends AttackCard>> pool = new HashMap<>();
public HashMap<String, HashSet<? extends AttackCard>> get() {
return pool;
}
superMap
的声明更改为:
private HashMap<String, HashMap<String, ? extends HashSet<? extends AttackCard>>> superMap = new HashMap<>();
HashMap<String, HashSet<Assassin>>
放入
superMap
。如何?想想看。
HashMap<String, HashSet<Assassin>>
可捕获转换为
HashMap<String, ? extends HashSet<? extends AttackCard>>
。对?因此,内部映射的以下分配有效:
HashMap<String, ? extends HashSet<? extends AttackCard>> map = new HashMap<String, HashSet<Assassin>>();
HashMap<String, HashSet<Assassin>>
中放入
superMap
。然后,您在
Assassin
类中的原始方法将可以正常工作。
superMap
的声明更改为:
Map<String, Map<String, ? extends Set<? extends AttackCard>>> superMap;
HashMap
或
TreeMap
或
LinkedHashMap
任意类型分配给
superMap
。另外,您将能够添加
HashMap
或
TreeMap
作为
superMap
的值。了解
Liskov Substitution Principle的用法非常重要。
关于java - Java HashMap使用通配符嵌套泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19219635/
我有不同的结构,它们都包含一个 HashMap与 String作为键,但具有不同的值类型。例如,一个结构有一个类型为 HashMap 的成员, 另一个将有一个 HashMap 类型的成员, 等等。 我
我想制作一个包含学生姓名和科目的板,每个学生在每个科目中都有一个成绩(或者没有..他可以离开考试而不写,然后他的案子将是空的)。我只想使用 HashMap。我的意思是,它会是这样的: HashMap>
是否有内存和速度高效的方法来在 HashMap 中动态存储唯一键:值对? key 保证是唯一的,但它们的数量经常变化。插入和删除必须很快。 我所做的是包含有符号距离场的八叉树(非线性/完整)。八叉树经
有谁知道为什么选择通过 LinkedList 而不是另一个 Hashmap 来实现 HashMap 的存储桶。如果桶本身变成了 HashMap,那么 contains 或 get 的时间复杂度似乎是
我想创建一个具有嵌套结构的 HashMap,就像这个复杂的示例: { type: boy name: Phineas father: type: man
这个问题在这里已经有了答案: How do I create a global, mutable singleton? (7 个答案) 关闭 7 年前。 我想要一个可扩展的字典,将 Object 与
HashMap> hm = new HashMap>(); hm.put("Title1","Key1"); for(int i=0;i hm1 = new H
我必须修改当前代码以适应 Spring MVC。我有 HashMap hashmap = new HashMap(); request.setAttribute("dslrErrors", hashm
我正在尝试进行一些错误捕获。 错误应该检查数组的长度是否小于 2,并检查 HashMap 是否包含用户输入的键。 捕获的错误必须仅使用 if 语句,并且必须使用 .length() 方法,并且必须使用
在 stackoverflow 上提出另一个问题后,(Java- Why this program not throwing concurrent Modification exception)我开始
我有两个类,想使用 org.dozer.Mapper( http://dozer.sourceforge.net/ ) 将 Female 对象的属性映射到 Male 对象。 第一类是: public
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be
是否有任何方法可以检查 HashMap 是否包含一组特定的键(这些键是在数组中给出的)。当我尝试类似下面的代码时,它返回 false。 map.containsKey(arrayOf("2018-01
跟进我的问题:How To Access hash maps key when the key is an object 我想尝试这样的事情:webSearchHash.put(xfile.getPa
我有一个可扩展的 ListView ,对于每个 child ,我需要有 4 个“额外”或字符串或其他名称来调用它:- 子标题- 描述- 链接1- 链接2 跟着教程,创建 ListView 、不同的 p
我想确保这是正确的,因为如果不正确,它可能会破坏我的应用程序。 我有这个: private static HashMap> balance = new HashMap<>(); 如果我得到这样的值:
我想做以下事情: 为某个键查找Vec,并将其存储以备后用。 如果它不存在,则为键创建一个空的 Vec,但仍将其保存在变量中。 如何有效地做到这一点?自然地,我认为我可以使用 match: use st
我想做以下事情: 为某个键查找Vec,并将其存储以备后用。 如果它不存在,则为键创建一个空的 Vec,但仍将其保存在变量中。 如何有效地做到这一点?自然地,我认为我可以使用 match: use st
我想做以下事情: 为某个键查找Vec,并将其存储以备后用。 如果它不存在,则为键创建一个空的 Vec,但仍将其保存在变量中。 如何有效地做到这一点?自然地,我认为我可以使用 match: use st
我想做以下事情: 为某个键查找Vec,并将其存储以备后用。 如果它不存在,则为键创建一个空的 Vec,但仍将其保存在变量中。 如何有效地做到这一点?自然地,我认为我可以使用 match: use st
我是一名优秀的程序员,十分优秀!