如何在 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 转换为 Map[]”。 奇怪,你是对的 - 猜我在实践中从未这样做过。【参考方案2】:

一般来说,在 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 可能会更好。如果您需要更改为SetCollection 的其他子接口之一,这可能会派上用场。示例代码:

Collection<Map<String,Integer>> maps = new HashSet<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());

从此开始,您只需将HashSet 更改为ArrayListPriorityQueue 或任何其他实现Collection 的类。

【讨论】:

你秒杀我。我可能会建议您改用 Collection,这样您也可以根据需要切换到 Set 实现。 @Drew:好主意!作为替代,我会将其添加到我的答案中。 您发布的链接表明执行 OP 所需的合法方法是 myMaps = new Map&lt;?,?&gt;[count]。但它也说这是一件危险的事情,将数组和通用容器混合在一起通常是一件坏事。 有人应该告诉 Springframework 团队,他们希望您为他们提供一组用于 JDBC 批处理操作的通用 Maps:NamedParameterJdbcTemplate.batchUpdate(String sql, Map&lt;String, ?&gt;[] 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&lt;Integer&gt; 包含一个 元素。第 3 行存储 List&lt;String&gt; 数组转换为 Object 数组变量,这是合法的,因为 数组是协变的。 4号线门店 将List&lt;Integer&gt; 放入鞋底 Object 数组的元素,其中 成功是因为泛型是 通过擦除实现:运行时 List&lt;Integer&gt; 实例的类型是 简单的List,以及运行时类型 List&lt;String&gt;[] 实例是 List[],所以 此作业不会生成 ArrayStoreException。现在我们在 麻烦。我们存储了一个List&lt;Integer&gt; 实例到一个数组中 宣布仅持有List&lt;String&gt; 实例。在第 5 行,我们检索 唯一列表中的唯一元素 这个数组。编译器自动 将检索到的元素转换为String, 但它是一个Integer,所以我们得到一个 ClassCastException 在运行时。在 为了防止这种情况发生, 第 1 行(创建一个通用数组) 生成编译时错误。

由于数组和泛型不能很好地结合(以及其他原因),通常最好使用Collection 对象(尤其是List 对象)而不是数组。

【讨论】:

这个例子在 IMO 上没有说服力。您已经可以使用普通数组更轻松地破坏类型安全 - 查看 ArrayStoreException。 这是重点。数组可以说是被破坏的,因为它们是协变的——你可以将一个子类数组分配给需要一个超类数组的东西。至少当您尝试插入不应该在数组中的东西时,您会得到 ArrayStoreException。使用泛型,您甚至不会得到异常。由于擦除,List 不会执行运行时检查您插入的内容实际上是 T 类型的。检查都是在编译时完成的,因此类型是静态合理的更为重要。跨度> 【参考方案6】:

我有一个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 中实例化一组地图?的主要内容,如果未能解决你的问题,请参考以下文章

谁能帮我用matlab归一化一组数据,需要运行结果,谢谢

安卓高德地图开发java如何调用js自定义图层

PHP单例模式简记

单例模式

从两个子类调用时仅实例化一次父类

如何初始化静态地图?