I can declare an array of maps using generics to specify the map type:
private Map<String, Integer>[] myMaps;
However, I can't figure out how to instantiate it properly:
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
How can I instantiate this array of maps without getting a compiler error or warning?
Update:
Thank you all for your replies. I ended up going with the List suggestion.
To initialize a Map with values, use the Map() constructor, passing it an array containing nested arrays of key-value pairs, where the first element in the array is the key and the second - the value. Each key-value pair is added to the new Map .
The Static Initializer for a Static HashMap We can also initialize the map using the double-brace syntax: Map<String, String> doubleBraceMap = new HashMap<String, String>() {{ put("key1", "value1"); put("key2", "value2"); }};
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With