如何在 Java 中实例化一组地图?
Posted
技术标签:
【中文标题】如何在 Java 中实例化一组地图?【英文标题】:How does one instantiate an array of maps in Java? 【发布时间】:2010-12-02 08:45:34 【问题描述】:我可以使用泛型声明一个映射数组来指定映射类型:
private Map<String, Integer>[] myMaps;
但是,我不知道如何正确实例化它:
myMaps = new HashMap<String, Integer>[count]; // gives "generic array creation" error
myMaps = new HashMap[count]; // gives an "unchecked or unsafe operation" warning
myMaps = (Map<String, Integer>[])new HashMap[count]; // also gives warning
如何实例化这个映射数组而不出现编译器错误或警告?
更新:
感谢大家的回复。我最终选择了 List 建议。
【问题讨论】:
【参考方案1】:myMaps = new HashMap<String, Integer>[10]();
那就错了
为什么不制作地图列表而不是尝试制作数组?
List<Map<String, Integer>> mymaps = new ArrayList<Map<String, Integer>>(count);
【讨论】:
不对:“类型不匹配:无法从 Map一般来说,在 Java 中混合泛型和数组并不是一个好主意,最好使用 ArrayList。
如果您必须使用数组,最好的处理方法是将数组创建(您的示例 2 或 3)放在单独的方法中,并使用 @SuppressWarnings("unchecked") 对其进行注释。
【讨论】:
@SuppressWarnings 是唯一不会收到警告的方法,但为什么要使用单独的方法呢?我觉得注释作业是一个更好的选择。 警告是说有些事情做错了。仅仅压制它是一个非常糟糕的主意。 @Tom Hawtin 如果它总是错误的,那将是错误而不是警告。因此,如果没有更好的方法来实现相同的目标,有时(很少)可以抑制警告。【参考方案3】:严格来说不是您问题的答案,但您是否考虑过使用List
代替?
List<Map<String,Integer>> maps = new ArrayList<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());
似乎工作得很好。
请参阅Java theory and practice: Generics gotchas,详细了解为什么不鼓励将数组与泛型混合使用。
更新:
正如 Drew 在 cmets 中提到的,使用Collection 接口而不是List
可能会更好。如果您需要更改为Set
或Collection
的其他子接口之一,这可能会派上用场。示例代码:
Collection<Map<String,Integer>> maps = new HashSet<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());
从此开始,您只需将HashSet
更改为ArrayList
、PriorityQueue
或任何其他实现Collection
的类。
【讨论】:
你秒杀我。我可能会建议您改用 Collection,这样您也可以根据需要切换到 Set 实现。 @Drew:好主意!作为替代,我会将其添加到我的答案中。 您发布的链接表明执行 OP 所需的合法方法是myMaps = new Map<?,?>[count]
。但它也说这是一件危险的事情,将数组和通用容器混合在一起通常是一件坏事。
有人应该告诉 Springframework 团队,他们希望您为他们提供一组用于 JDBC 批处理操作的通用 Maps:NamedParameterJdbcTemplate.batchUpdate(String sql, Map<String, ?>[] batchValues)
docs.spring.io/spring-framework/docs/current/javadoc-api/org/…【参考方案4】:
简短的回答似乎是你真的不能。
有关它的博客,请参阅以下内容。 http://www.bloggingaboutjava.org/2006/01/java-generics-quirks/
博客中的一位 cmet 指出:
实际上,工程师们认为创建这样的阵列是非法的。因此,从泛型 Class 创建数组失败。 Collection.toArray 方法后跟 Cast to the Array 在编译时起作用。
这并没有解决问题,即 ArrayStoreCheck 无法在运行时完成,但您可以通过这种方式创建一个泛型数组。
根据蜥蜴比尔的建议,您可能最好使用 a
List<Map<String,Integer>>
【讨论】:
【参考方案5】:您无法安全地创建泛型数组。 Effective Java 2nd Edition 在chapter on Generics 中详细介绍。从第 119 页的最后一段开始:
为什么创建泛型是非法的 大批?因为它不是类型安全的。如果 这是合法的,由 编译器以其他方式正确 程序可能在运行时失败
ClassCastException
。这将违反 提供的根本保障 泛型类型系统。为了更具体,请考虑 以下代码片段:
// Why generic array creation is illegal - won't compile! List<String>[] stringLists = new List<String>[1]; // (1) List<Integer> intList = Arrays.asList(42); // (2) Object[] objects = stringLists; // (3) objects[0] = intList; // (4) String s = stringLists[0].get(0); // (5)
让我们假设第 1 行,它 创建一个泛型数组,是合法的。 第 2 行创建并初始化一个
List<Integer>
包含一个 元素。第 3 行存储List<String>
数组转换为Object
数组变量,这是合法的,因为 数组是协变的。 4号线门店 将List<Integer>
放入鞋底Object
数组的元素,其中 成功是因为泛型是 通过擦除实现:运行时List<Integer>
实例的类型是 简单的List
,以及运行时类型List<String>[]
实例是List[]
,所以 此作业不会生成ArrayStoreException
。现在我们在 麻烦。我们存储了一个List<Integer>
实例到一个数组中 宣布仅持有List<String>
实例。在第 5 行,我们检索 唯一列表中的唯一元素 这个数组。编译器自动 将检索到的元素转换为String
, 但它是一个Integer
,所以我们得到一个ClassCastException
在运行时。在 为了防止这种情况发生, 第 1 行(创建一个通用数组) 生成编译时错误。
由于数组和泛型不能很好地结合(以及其他原因),通常最好使用Collection
对象(尤其是List
对象)而不是数组。
【讨论】:
这个例子在 IMO 上没有说服力。您已经可以使用普通数组更轻松地破坏类型安全 - 查看 ArrayStoreException。 这是重点。数组可以说是被破坏的,因为它们是协变的——你可以将一个子类数组分配给需要一个超类数组的东西。至少当您尝试插入不应该在数组中的东西时,您会得到 ArrayStoreException。使用泛型,您甚至不会得到异常。由于擦除,List我有一个similar question,最好的回复是this
【讨论】:
【参考方案7】:您可以创建通用地图数组
创建地图列表。
List<Map<String, ?>> myData = new ArrayList<Map<String, ?>>();
初始化数组。
Map<String,?>[]myDataArray=new HashMap[myData .size()];
从列表中填充数组中的数据。
myDataArray=myData.toArray(myDataArry);
【讨论】:
【参考方案8】:我知道回复有点晚了,但我发现这个解决方法对我的情况很有帮助...希望它有所帮助!
使用一个HashMap数组来存储HashMaps..
public static void main(String[] args)
HashMap[] arr = new HashMap[1];//creating an array of size one..just for sake of example
HashMap<String, String> arrMap = new HashMap<String, String>();
//use loops to store desired key-value pairs into the HashMap which will be stored inside the array
arrMap.put("ABC", "Name");
//use loop to store your desired hashMap into the array at a particular index
arr[0] = arrMap;
//desired manipulation of the stored array.
System.out.println(arr[0]);
【讨论】:
以上是关于如何在 Java 中实例化一组地图?的主要内容,如果未能解决你的问题,请参考以下文章