实例化地图列表时获取 'Type mismatch: cannot convert from ArrayList<HashMap<String,String>> to List<Map<String,String>>'
Getting 'Type mismatch: cannot convert from ArrayList<HashMap<String,String>> to List<Map<String,String>>' while instantiating a list of maps
List<Map<String, String>> recordMapList = new ArrayList<HashMap<String,String>>();
上面一行给出了错误:
类型不匹配:无法从 ArrayList> 转换为 List>
但如果在左侧使用 HashMap 而不是 Map,问题就会消失。
谁能告诉我为什么会这样。
我需要在左侧包含 Map,因为我可能会使用相同的变量在右侧分配 LinkedHashMap,例如
List<Map<String, String>> recordMapList = new ArrayList<LinkedHashMap <String,String>>();
请帮忙。
原因是 List<HashMap>
不是 List<Map>
的子 class
解决方法,不需要声明为:
List<Map<String, String>> recordMapList = new ArrayList<HashMap<String,String>>();
您可以声明为:
List<Map<String, String>> recordMapList = new ArrayList<Map<String,String>>();
然后将HashMap
放入recordMapList
.
我建议您避免实例化具有给定泛型类型的列表,即:
List<Map<String, String>> recordMapList = new ArrayList<>();
这是从 Java 7 开始的泛型赋值约定(从这个版本开始,赋值集合的泛型类型是通过声明的类型推断的)。为什么?由于在声明通用列表变量时已经明确声明了列表值的声明类型。这些值是地图接口的实例,将在代码实现中提供。
访问列表值时,重要的是所使用的接口 (Map
),而不是其实现 (HashMap
)。这样,如果 Map
实现被替换,则无需更改 recordMapList
.
的分配值
请参阅以下示例(显示列表如何不受 Map
的实现约束):
List<Map<String,String>> recordMapList = new ArrayList<>(); // Declaration + Assignment
recordMapList.add(new HashMap<>()); // Add a first implementation of Map
recordMapList.add(new TreeMap<>()); // Add a second implementation of Map
参考:
奖金:
虽然 ArrayList
是 List
的子 class,并且 Map
是 HashMap
的子 class,但 List<Map>
不是 List<HashMap>
的子 class。同样,您不能将 List<HashMap>
转换为 List<Map>
。如果可以的话,这意味着我们可以将 TreeMap
添加到我们的 List<Map>
,然后将其转换为 List<HashMap>
,从而违反 List<HashMap>
的原始合同.
如果立即创建 recordMapList
-实例,我个人只会使用菱形运算符 (Java 7+):
List<Map<String, String>> recordMapList = new ArrayList<>();
如果它是在其他地方创建的,那么只有 List
可以是 ArrayList
,但其余的都是一样的。 (注意:您当然也可以在这里使用菱形运算符,但是如果创建实例和实际字段是分开的,我个人更喜欢使用类型,这样可以立即清楚列表中的类型,而无需跳转到代码中的实际字段。)
List<Map<String, String>> recordMapList;
...
recordMapList = new ArrayList<Map<String, String>>();
在这两种情况下,您都可以将 HashMap<String, String>
个实例添加到 recordMapList
。
List<Map<String, String>> recordMapList = new ArrayList<HashMap<String,String>>();
上面一行给出了错误: 类型不匹配:无法从 ArrayList> 转换为 List>
但如果在左侧使用 HashMap 而不是 Map,问题就会消失。 谁能告诉我为什么会这样。 我需要在左侧包含 Map,因为我可能会使用相同的变量在右侧分配 LinkedHashMap,例如
List<Map<String, String>> recordMapList = new ArrayList<LinkedHashMap <String,String>>();
请帮忙。
原因是 List<HashMap>
不是 List<Map>
解决方法,不需要声明为:
List<Map<String, String>> recordMapList = new ArrayList<HashMap<String,String>>();
您可以声明为:
List<Map<String, String>> recordMapList = new ArrayList<Map<String,String>>();
然后将HashMap
放入recordMapList
.
我建议您避免实例化具有给定泛型类型的列表,即:
List<Map<String, String>> recordMapList = new ArrayList<>();
这是从 Java 7 开始的泛型赋值约定(从这个版本开始,赋值集合的泛型类型是通过声明的类型推断的)。为什么?由于在声明通用列表变量时已经明确声明了列表值的声明类型。这些值是地图接口的实例,将在代码实现中提供。
访问列表值时,重要的是所使用的接口 (Map
),而不是其实现 (HashMap
)。这样,如果 Map
实现被替换,则无需更改 recordMapList
.
请参阅以下示例(显示列表如何不受 Map
的实现约束):
List<Map<String,String>> recordMapList = new ArrayList<>(); // Declaration + Assignment
recordMapList.add(new HashMap<>()); // Add a first implementation of Map
recordMapList.add(new TreeMap<>()); // Add a second implementation of Map
参考:
奖金:
虽然 ArrayList
是 List
的子 class,并且 Map
是 HashMap
的子 class,但 List<Map>
不是 List<HashMap>
的子 class。同样,您不能将 List<HashMap>
转换为 List<Map>
。如果可以的话,这意味着我们可以将 TreeMap
添加到我们的 List<Map>
,然后将其转换为 List<HashMap>
,从而违反 List<HashMap>
的原始合同.
如果立即创建 recordMapList
-实例,我个人只会使用菱形运算符 (Java 7+):
List<Map<String, String>> recordMapList = new ArrayList<>();
如果它是在其他地方创建的,那么只有 List
可以是 ArrayList
,但其余的都是一样的。 (注意:您当然也可以在这里使用菱形运算符,但是如果创建实例和实际字段是分开的,我个人更喜欢使用类型,这样可以立即清楚列表中的类型,而无需跳转到代码中的实际字段。)
List<Map<String, String>> recordMapList;
...
recordMapList = new ArrayList<Map<String, String>>();
在这两种情况下,您都可以将 HashMap<String, String>
个实例添加到 recordMapList
。