如何在Java中实例化一组地图?

时间:2009-09-29 15:06:49

标签: java arrays generics map instantiation

我可以使用泛型声明一个地图数组来指定地图类型:

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建议。

8 个答案:

答案 0 :(得分:38)

对您的问题不是一个严格的答案,但您是否考虑使用List代替?

List<Map<String,Integer>> maps = new ArrayList<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());

似乎工作正常。

有关为何不鼓励将数组与泛型混合的详细说明,请参阅Java theory and practice: Generics gotchas

更新

正如Drew在评论中所提到的,使用Collection界面而不是List可能更好。如果您需要更改为SetCollection的其他子接口之一,这可能会派上用场。示例代码:

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

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

答案 1 :(得分:18)

您无法安全地创建通用数组。有效的Java第二版详细介绍了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行创建并初始化a   List<Integer>包含一个   元件。 3号线存储了   List<String>数组Object   数组变量,这是合法的,因为   数组是协变的。 4号线商店   List<Integer>进入鞋底   Object数组的元素,其中   成功,因为泛型是   通过擦除实现:运行时   List<Integer>实例的类型是   简单地List,以及a的运行时类型   List<String>[]实例是List[],所以   这项任务不会产生   ArrayStoreException。现在我们进来了   麻烦。我们存储了List<Integer>   实例进入一个数组   宣布仅持有List<String>   实例。在第5行,我们检索   来自唯一名单的唯一元素   这个数组。编译器自动完成   将检索到的元素强制转换为String,   但它是Integer,所以我们得到了   ClassCastException在运行时。在   为了防止这种情况发生,   第1行(创建一个通用数组)   生成编译时错误。

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

答案 2 :(得分:5)

一般来说,在Java中混合泛型和数组并不是一个好主意,最好使用ArrayList。

如果必须使用数组,处理此问题的最佳方法是将数组创建(示例2或3)放在单独的方法中,并使用@SuppressWarnings(“unchecked”)对其进行注释。

答案 3 :(得分:2)

简短的回答似乎是你真的不能。

有关它的博客请参阅以下内容。 http://www.bloggingaboutjava.org/2006/01/java-generics-quirks/

该博客的一条评论指出:

  

实际上,工程师使这种阵列的创建非法。因此,从泛型类创建数组失败。 Collection.toArray方法后跟Cast转换为数组在编译时工作。

     

这解决了问题,即在运行时无法完成ArrayStoreCheck,但是你可以用这种方式创建一个泛型数组。

根据比尔蜥蜴的建议,你可能最好使用

List<Map<String,Integer>>

答案 4 :(得分:2)

您可以创建地图的通用数组

  1. 创建地图列表。

     List<Map<String, ?>> myData = new ArrayList<Map<String, ?>>();
    
  2. 初始化数组。

     Map<String,?>[]myDataArray=new HashMap[myData .size()];
    
  3. 从列表中填充数组中的数据。

     myDataArray=myData.toArray(myDataArry);
    

答案 5 :(得分:1)

我知道现在答复有点晚了,但是我发现此解决方法对我的情况很有帮助...希望有帮助!

使用HashMap数组存储HashMap。.

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]);
}

答案 6 :(得分:-1)

我有一个similar question,最好的回复我被提到this

答案 7 :(得分:-5)

myMaps = new HashMap<String, Integer>[10]();

这是错误的

为什么不制作地图列表而不是尝试制作数组?

List<Map<String, Integer>> mymaps = new ArrayList<Map<String, Integer>>(count);