How does one instantiate an array of maps in Java?
Not strictly an answer to your question, but have you considered using a List
instead?
List<Map<String,Integer>> maps = new ArrayList<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());
seems to work just fine.
See Java theory and practice: Generics gotchas for a detailed explanation of why mixing arrays with generics is discouraged.
Update:
As mentioned by Drew in the comments, it might be even better to use the Collection interface instead of List
. This might come in handy if you ever need to change to a Set
, or one of the other subinterfaces of Collection
. Example code:
Collection<Map<String,Integer>> maps = new HashSet<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());
From this starting point, you'd only need to change HashSet
to ArrayList
, PriorityQueue
, or any other class that implements Collection
.
You can't safely create a generic array. Effective Java 2nd Edition goes into the details in the chapter on Generics. Start at the last paragraph of page 119:
Why is it illegal to create a generic array? Because it isn’t typesafe. If it were legal, casts generated by the compiler in an otherwise correct program could fail at runtime with a
ClassCastException
. This would violate the fundamental guarantee provided by the generic type system.To make this more concrete, consider the following code fragment:
// 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)
Let’s pretend that line 1, which creates a generic array, is legal. Line 2 creates and initializes a
List<Integer>
containing a single element. Line 3 stores theList<String>
array into anObject
array variable, which is legal because arrays are covariant. Line 4 stores theList<Integer>
into the sole element of theObject
array, which succeeds because generics are implemented by erasure: the runtime type of aList<Integer>
instance is simplyList
, and the runtime type of aList<String>[]
instance isList[]
, so this assignment doesn’t generate anArrayStoreException
. Now we’re in trouble. We’ve stored aList<Integer>
instance into an array that is declared to hold onlyList<String>
instances. In line 5, we retrieve the sole element from the sole list in this array. The compiler automatically casts the retrieved element toString
, but it’s anInteger
, so we get aClassCastException
at runtime. In order to prevent this from happening, line 1 (which creates a generic array) generates a compile-time error.
Because arrays and generics don't combine well (as well as other reasons), it's generally better to use Collection
objects (in particular List
objects) rather than arrays.