Java unmodifiable array - java

final Integer[] arr={1,2,3};
arr[0]=3;
System.out.println(Arrays.toString(arr));
I tried the above code to see whether a final array's variables can be reassigned[ans:it can be].I understand that by a final Integer[] array it means we cannot assign another instance of Integer[] apart from the one we have assigned initially.I would like to know if whether it is possible to make the array variables also unmodifiable.

This isn't possible as far as I know.
There is however a method Collections.unmodifiableList(..) which creates an unmodifiable view of e.g. a List<Integer>.
If you want to guarantee that not even the creator of the unmodifiable view list will be able to modify the underlying (modifiable) list, have a look at Guava's ImmutableList.

No. The contents of an array can be changed. You can't prevent that.
Collections has various methods for creating unmodifiable collections, but arrays aren't provided for.

The final keyword only prevents changing the arr reference, i.e. you can't do:
final int[] arr={1,2,3};
arr = new int[5];
If the object arr is referring to is mutable object (like arrays), nothing prevents you from modifying it.
The only solution is to use immutable objects.

Another way is to use this function:
Arrays.copyOf(arr, arr.length);

The keyword 'final' applies to only the references (pointer to the memory location of the object in the heap). You can't change the memory address (location) of the object. Its upto your object how it internally handles the immutability.
Added, although int is a primitive data type int[] should be treated as a object.
You can't do this
final int a = 5
a = 6
You can do this:
final int[] a = new int[]{2,3,4};
a[0] = 6;
You can't do this:
final int[] a = new int[]{2,3,4};
a = new int[]{1,2,3}

To anybody else reading this old question, keep in mind there is also Google Guava's immutable collections. ImmutableList has much stronger performance than Collections.unmodifiableList(), and is arguably safer as it truly is immutable,and not backed by a mutable collection.

I'd go with List.of(array), as available from Java 9 on, which creates a copy of the source array internally and an immutable List from that. Note though, there there're no null values allowed in this implementation.
If this is a requirement, Arrays.copyOf([T]source, int length) can be used, if no real immutability is needed, but only the source array mustn't be modified.
Otherwise, if immutability of the target Collection is required, Java's immutable Collection API or Guava might be your best shot e. g. Collections.immutableXX() or ImmutableList.of().
If additional dependencies are not desired, one of the following approaches should work, depending on, whether further pre-processing is needed, before making the result immutable:
final T[] objects = (T[])new Object[] { null };
final T obj = (T)new Object();
final BinaryOperator<ArrayList<T>> listCombiner = (a,b) -> { a.addAll(b); return a; };
final Collector<T, ArrayList<T>, List<T>> collector = Collector.of(
ArrayList<T>::new, List::add, listCombiner, Collections::unmodifiableList
);
final List<T> list = Arrays.stream(objects).collect(collector);
or simply
final List<T> list = Collections.unmodifiableList(Arrays.asList(objects ));
Edit:
As already outlined, creating an immutable array in itself is not possible in Java.

Related

Why does Arrays.asList() behave the way it does with primitive arrays? [duplicate]

I have a float[] and i would like to get a list with the same elements. I could do the ugly thing of adding them one by one but i wanted to use the Arrays.asList method. There is a problem though. This works:
List<Integer> list = Arrays.asList(1,2,3,4,5);
But this does not.
int[] ints = new int[] {1,2,3,4,5};
List<Integer> list = Arrays.asList(ints);
The asList method accepts a varargs parameter which to the extends of my knowledge is a "shorthand" for an array.
Questions:
Why does the second piece of code returns a List<int[]> but not List<int>.
Is there a way to correct it?
Why doesn't autoboxing work here; i.e. int[] to Integer[]?
There's no such thing as a List<int> in Java - generics don't support primitives.
Autoboxing only happens for a single element, not for arrays of primitives.
As for how to correct it - there are various libraries with oodles of methods for doing things like this. There's no way round this, and I don't think there's anything to make it easier within the JDK. Some will wrap a primitive array in a list of the wrapper type (so that boxing happens on access), others will iterate through the original array to create an independent copy, boxing as they go. Make sure you know which you're using.
(EDIT: I'd been assuming that the starting point of an int[] was non-negotiable. If you can start with an Integer[] then you're well away :)
Just for one example of a helper library, and to plug Guava a bit, there's com.google.common.primitive.Ints.asList.
How about this?
Integer[] ints = new Integer[] {1,2,3,4,5};
List<Integer> list = Arrays.asList(ints);
Because java arrays are objects and Arrays.asList() treats your int array as a single argument in the varargs list.
Enter Java 8, and you can do following to collect in a boxed Array:
Integer[] boxedInts = IntStream.of(ints).boxed().toArray(Integer[]::new);
Or this to collect in a boxed List
List<Integer> boxedInts = IntStream.of(ints).boxed().collect(Collectors.toList());
However, this only works for int[], long[], and double[]. This will not work for byte[].
Note that Arrays.stream(ints) and IntStream.of(ints) are equivalent. So earlier two examples can also be rewritten as:
Integer[] boxedIntArray = Arrays.stream(ints).boxed().toArray(Integer[]::new);
List<Integer> boxedIntList = Arrays.stream(ints).boxed().collect(Collectors.toList());
This last form could be favored as it omits a primitive specific subtype of Stream. However, internally it is still a bunch of overloaded's which in this case still create a IntStream internally.
The problem is not with Arrays.asList(). The problem is that you expect autoboxing to work on an array - and it doesn't. In the first case, the compiler autoboxes the individual ints before it looks at what they're used for. In the second case, you first put them into an int array (no autoboxing necessary) and then pass that to Arrays.asList() (not autoboxing possible).
Arrays.asList(T... a) effectively takes a T[] which will match any array of true objects (subclasses of Object) as an array. The only thing that won't match like that is an array of primitives, since primitive types do not derive from Object. So an int[] is not an Object[].
What happens then is that the varags mechanism kicks in and treats it as if you had passed a single object, and creates a single element array of that type. So you pass an int[][] (here, T is int[]) and end up with a 1-element List<int[]> which is not what you want.
You still have some pretty good options though:
Guava's Int.asList(int[]) Adapter
If your project already uses guava, it's as simple as using the adapter Guava provides: Int.asList(). There is a similar adapter for each primitive type in the associated class, e.g., Booleans for boolean, etc.
int foo[] = {1,2,3,4,5};
Iterable<Integer> fooBar = Ints.asList(foo);
for(Integer i : fooBar) {
System.out.println(i);
}
The advantage of this approach is that it creates a thin wrapper around the existing array, so the creation of the wrapper is constant time (doesn't depend on the size of the array), and the storage required is only a small constant amount (less than 100 bytes) in addition to the underlying integer array.
The downside is that accessing each element requires a boxing operation of the underlying int, and setting requires unboxing. This may result in a large amount of transient memory allocation if you access the list heavily. If you access each object many times on average, it may be better to use an implementation that boxes the objects once and stores them as Integer. The solution below does that.
Java 8 IntStream
In Java 8, you can use the Arrays.stream(int[]) method to turn an int array into a Stream. Depending on your use case, you may be able to use the stream directly, e.g., to do something with each element with forEach(IntConsumer). In that case, this solution is very fast and doesn't incur any boxing or unboxing at all, and does not create any copy of the underlying array.
Alternately, if you really need a List<Integer>, you can use stream.boxed().collect(Collectors.toList()) as suggested here. The downside of that approach is that it fully boxes every element in the list, which might increase its memory footprint by nearly an order of magnitude, it create a new Object[] to hold all the boxed elements. If you subsequently use the list heavily and need Integer objects rather than ints, this may pay off, but it's something to be aware of.
Why doesn't autoboxing work here; i.e. int[] to Integer[]?
While autoboxing will convert an int to an Integer, it will not convert an int[] to an Integer[].
Why not?
The simple (but unsatisfying) answer is because that is what the JLS says. (You can check it if you like.)
The real answer is fundamental to what autoboxing is doing and why it is safe.
When you autobox 1 anywhere in your code, you get the same Integer object. This is not true for all int values (due to the limited size of the Integer autoboxing cache), but if you use equals to compare Integer objects you get the "right" answer.
Basically N == N is always true and new Integer(N).equals(new Integer(N)) is always true. Furthermore, these two things remain true ... assuming that you stick with Pure Java code.
Now consider this:
int[] x = new int[]{1};
int[] y = new int[]{1};
Are these equal? No! x == y is false and x.equals(y) is false! But why? Because:
y[0] = 2;
In other words, two arrays with the same type, size and content are always distinguishable because Java arrays are mutable.
The "promise" of autoboxing is that it is OK to do because the results are indistinguishable1. But, because all arrays are fundamentally distinguishable because of the definition of equals for arrays AND array mutability. So, if autoboxing of arrays of primitive types was permitted, it would undermine the "promise".
1 - ..... provided that you don't use == to test if autoboxed values are equal.
If you pass an int[] to Arrays.asList(), the list created will be List<int[]>, which is not vaild in java, not the correct List<Integer>.
I think you are expecting Arrays.asList() to auto-box your ints, which as you have seen, it won't.
It's not possible to convert int[] to Integer[], you have to copy values
int[] tab = new int[]{1, 2, 3, 4, 5};
List<Integer> list = ArraysHelper.asList(tab);
public static List<Integer> asList(int[] a) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < a.length && list.add(a[i]); i++);
return list;
}
Alternatively, you can use IntList as the type and the IntLists factory from Eclipse Collections to create the collection directly from an array of int values. This removes the need for any boxing of int to Integer.
IntList intList1 = IntLists.mutable.with(1,2,3,4,5);
int[] ints = new int[] {1,2,3,4,5};
IntList intList2 = IntLists.mutable.with(ints);
Assert.assertEquals(intList1, intList2);
Eclipse Collections has support for mutable and immutable primitive List as well as Set, Bag, Stack and Map.
Note: I am a committer for Eclipse Collections.
int is a primitive type. Arrays.asList() accept generic type T which only works on reference types (object types), not on primitives. Since int[] as a whole is an object it can be added as a single element.
There is a better solution for this starting with Java 9:
List<Integer> list = List.of(null, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8);

indexOf incorrectly says that an integer isn't in an array [duplicate]

I have a float[] and i would like to get a list with the same elements. I could do the ugly thing of adding them one by one but i wanted to use the Arrays.asList method. There is a problem though. This works:
List<Integer> list = Arrays.asList(1,2,3,4,5);
But this does not.
int[] ints = new int[] {1,2,3,4,5};
List<Integer> list = Arrays.asList(ints);
The asList method accepts a varargs parameter which to the extends of my knowledge is a "shorthand" for an array.
Questions:
Why does the second piece of code returns a List<int[]> but not List<int>.
Is there a way to correct it?
Why doesn't autoboxing work here; i.e. int[] to Integer[]?
There's no such thing as a List<int> in Java - generics don't support primitives.
Autoboxing only happens for a single element, not for arrays of primitives.
As for how to correct it - there are various libraries with oodles of methods for doing things like this. There's no way round this, and I don't think there's anything to make it easier within the JDK. Some will wrap a primitive array in a list of the wrapper type (so that boxing happens on access), others will iterate through the original array to create an independent copy, boxing as they go. Make sure you know which you're using.
(EDIT: I'd been assuming that the starting point of an int[] was non-negotiable. If you can start with an Integer[] then you're well away :)
Just for one example of a helper library, and to plug Guava a bit, there's com.google.common.primitive.Ints.asList.
How about this?
Integer[] ints = new Integer[] {1,2,3,4,5};
List<Integer> list = Arrays.asList(ints);
Because java arrays are objects and Arrays.asList() treats your int array as a single argument in the varargs list.
Enter Java 8, and you can do following to collect in a boxed Array:
Integer[] boxedInts = IntStream.of(ints).boxed().toArray(Integer[]::new);
Or this to collect in a boxed List
List<Integer> boxedInts = IntStream.of(ints).boxed().collect(Collectors.toList());
However, this only works for int[], long[], and double[]. This will not work for byte[].
Note that Arrays.stream(ints) and IntStream.of(ints) are equivalent. So earlier two examples can also be rewritten as:
Integer[] boxedIntArray = Arrays.stream(ints).boxed().toArray(Integer[]::new);
List<Integer> boxedIntList = Arrays.stream(ints).boxed().collect(Collectors.toList());
This last form could be favored as it omits a primitive specific subtype of Stream. However, internally it is still a bunch of overloaded's which in this case still create a IntStream internally.
The problem is not with Arrays.asList(). The problem is that you expect autoboxing to work on an array - and it doesn't. In the first case, the compiler autoboxes the individual ints before it looks at what they're used for. In the second case, you first put them into an int array (no autoboxing necessary) and then pass that to Arrays.asList() (not autoboxing possible).
Arrays.asList(T... a) effectively takes a T[] which will match any array of true objects (subclasses of Object) as an array. The only thing that won't match like that is an array of primitives, since primitive types do not derive from Object. So an int[] is not an Object[].
What happens then is that the varags mechanism kicks in and treats it as if you had passed a single object, and creates a single element array of that type. So you pass an int[][] (here, T is int[]) and end up with a 1-element List<int[]> which is not what you want.
You still have some pretty good options though:
Guava's Int.asList(int[]) Adapter
If your project already uses guava, it's as simple as using the adapter Guava provides: Int.asList(). There is a similar adapter for each primitive type in the associated class, e.g., Booleans for boolean, etc.
int foo[] = {1,2,3,4,5};
Iterable<Integer> fooBar = Ints.asList(foo);
for(Integer i : fooBar) {
System.out.println(i);
}
The advantage of this approach is that it creates a thin wrapper around the existing array, so the creation of the wrapper is constant time (doesn't depend on the size of the array), and the storage required is only a small constant amount (less than 100 bytes) in addition to the underlying integer array.
The downside is that accessing each element requires a boxing operation of the underlying int, and setting requires unboxing. This may result in a large amount of transient memory allocation if you access the list heavily. If you access each object many times on average, it may be better to use an implementation that boxes the objects once and stores them as Integer. The solution below does that.
Java 8 IntStream
In Java 8, you can use the Arrays.stream(int[]) method to turn an int array into a Stream. Depending on your use case, you may be able to use the stream directly, e.g., to do something with each element with forEach(IntConsumer). In that case, this solution is very fast and doesn't incur any boxing or unboxing at all, and does not create any copy of the underlying array.
Alternately, if you really need a List<Integer>, you can use stream.boxed().collect(Collectors.toList()) as suggested here. The downside of that approach is that it fully boxes every element in the list, which might increase its memory footprint by nearly an order of magnitude, it create a new Object[] to hold all the boxed elements. If you subsequently use the list heavily and need Integer objects rather than ints, this may pay off, but it's something to be aware of.
Why doesn't autoboxing work here; i.e. int[] to Integer[]?
While autoboxing will convert an int to an Integer, it will not convert an int[] to an Integer[].
Why not?
The simple (but unsatisfying) answer is because that is what the JLS says. (You can check it if you like.)
The real answer is fundamental to what autoboxing is doing and why it is safe.
When you autobox 1 anywhere in your code, you get the same Integer object. This is not true for all int values (due to the limited size of the Integer autoboxing cache), but if you use equals to compare Integer objects you get the "right" answer.
Basically N == N is always true and new Integer(N).equals(new Integer(N)) is always true. Furthermore, these two things remain true ... assuming that you stick with Pure Java code.
Now consider this:
int[] x = new int[]{1};
int[] y = new int[]{1};
Are these equal? No! x == y is false and x.equals(y) is false! But why? Because:
y[0] = 2;
In other words, two arrays with the same type, size and content are always distinguishable because Java arrays are mutable.
The "promise" of autoboxing is that it is OK to do because the results are indistinguishable1. But, because all arrays are fundamentally distinguishable because of the definition of equals for arrays AND array mutability. So, if autoboxing of arrays of primitive types was permitted, it would undermine the "promise".
1 - ..... provided that you don't use == to test if autoboxed values are equal.
If you pass an int[] to Arrays.asList(), the list created will be List<int[]>, which is not vaild in java, not the correct List<Integer>.
I think you are expecting Arrays.asList() to auto-box your ints, which as you have seen, it won't.
It's not possible to convert int[] to Integer[], you have to copy values
int[] tab = new int[]{1, 2, 3, 4, 5};
List<Integer> list = ArraysHelper.asList(tab);
public static List<Integer> asList(int[] a) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < a.length && list.add(a[i]); i++);
return list;
}
Alternatively, you can use IntList as the type and the IntLists factory from Eclipse Collections to create the collection directly from an array of int values. This removes the need for any boxing of int to Integer.
IntList intList1 = IntLists.mutable.with(1,2,3,4,5);
int[] ints = new int[] {1,2,3,4,5};
IntList intList2 = IntLists.mutable.with(ints);
Assert.assertEquals(intList1, intList2);
Eclipse Collections has support for mutable and immutable primitive List as well as Set, Bag, Stack and Map.
Note: I am a committer for Eclipse Collections.
int is a primitive type. Arrays.asList() accept generic type T which only works on reference types (object types), not on primitives. Since int[] as a whole is an object it can be added as a single element.
There is a better solution for this starting with Java 9:
List<Integer> list = List.of(null, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8);

modifying a public static final array

While designing a small API, i was about to write a static value that references to an array of String:
public static final String[] KEYS={"a","b","c"}
I have found this to be marked as a 'security hole' in Joshua Bloch's 'Effective Java' item 14, where he proposes as an alternative, declaring te array 'private' and provide a public getter that returns an unmodifiable list:
return Collections.unmodifiableList(Arrays.asList(KEYS))
I just cant see why would this be necessary, the array in the initial statement is declared final even though its public, and its elements are immutable, how could that be modified from an external piece of code?
The array is not immutable.
You can still write:
KEYS[0] = "d";
without any issues.
final just means you cannot write:
KEYS = new String[]{"d"};
I.e. you cannot assign a new value to the variable KEYS.
final means
You can't change the Basket. Still you can change the fruits inside.
Basket is your Array instance. Fruits are your keys inside.
In first case, from somewhere else in the code, I can do
ClassName.KEYS[2] ="MyOwnValue";
But you can't modify when it is unmodifiable list.
Give a shot to read : Why final instance class variable in Java?
While the array reference itself is immutable (you cannot replace it with a reference to another array) and the Strings themselves are immutable too it is still possible to write
KEYS[0] = "new Key";
A composite object ( array , Set , List etc ) being final doesn't mean that its constituent objects will not be changed - you can still change constituent objects . final for a composite object simply means that its reference can't be changed.
For your case, value of KEYS can't be changed but KEYS[0] etc can be changed.

Java array declaration without hard coding the size

How can I initialize an array of objects of a class in another class without hardcoding its size?
Use a List. The size does not need to be declared on creation of the List. The toArray() method will return an array representation of the list. There are multiple implementations you can use but the most popular tends to be ArrayList (though it is best to map the implementation to your particular situation).
Arrays have a fixed size after creation. The size doesn't need to be known at compile-time, but it does need to be known at creation time. For example:
public String[] createArray(int size) {
// Not hard-coded, but array is not expandable
return new String[size];
}
If you want a collection which can grow an shrink over time, look at the various List<E> implementations, such as ArrayList<E>.
Arrays are fixed in length. I would recommend using a Collection.
Here is an article on collections:
http://en.wikipedia.org/wiki/Java_collections_framework
With these, you can add elements by using an Add() command or something similar.
As mentioned in the previous answers, an ArrayList or List are collections.
Object[] will always be fixed size. If you need a variable length collection, try ArrayList, LinkedList, or one of the many others.
Pick the collection carefully, since they all have different performance aspects.
For mutable arrays other container objects are used.
When using a set of objects, an ArrayList or Vector object is used.
You can also store objects with an object key e.g. "Name" = "Ben" instead of [0] = "Ben".
Vector v = new Vector();
for(int i = 0; i < 100; i++){
Object o = new Object();
// init object
v.addElement(o);
}
for(int i = 0; i < 100; i++){
Object o = v.elementAt(i);
// manipulate object
}
Now you have an arbritairy list of object of undefined length.
Size found by using vector.size() method.
java.util package is required and part of J2SE 1.3 and higher.
As noted elsewhere, an array object has a fixed size. If there's some reason you must use an array, you can use one or both of these techniques:
Make it the larger than you need, leaving the unused
entries null. You may want to keep a "slotsUsed" variable.
When the array gets too small, make a bigger one and copy the
contents into it.
These are both used inside ArrayList.
You can create a new array and initialize it like this.
String[] strArray = {"Initialize","Array","Like","This"};
If you want an array with a dynamic size I would recommend using an ArrayList.
If you want an array of primitive instead of objects, you can use Trove4j. Otherwise use an ArrayList, or CopyOnWriteArrayList to wrap an array. There are other List implementations but these do not act like arrays for access time.
Sometimes it is useful, in case you know an upper bound of the objects your application needs,
to declare the size of an array as
static final int ARRAY_SIZE = 1000;
This goes near the beginning of the class so it can be easily changed.
In the main code instantiate the array with
Object[] objects = new Object[ARRAY_SIZE];
Also in case the array you want to use has the same size as another array consider using
Object[] objects = new Object[other_objects.length];

How does one instantiate an array of maps in Java?

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.
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 the
List<String> array into an Object
array variable, which is legal because
arrays are covariant. Line 4 stores
the List<Integer> into the sole
element of the Object array, which
succeeds because generics are
implemented by erasure: the runtime
type of a List<Integer> instance is
simply List, and the runtime type of a
List<String>[] instance is List[], so
this assignment doesn’t generate an
ArrayStoreException. Now we’re in
trouble. We’ve stored a List<Integer>
instance into an array that is
declared to hold only List<String>
instances. In line 5, we retrieve the
sole element from the sole list in
this array. The compiler automatically
casts the retrieved element to String,
but it’s an Integer, so we get a
ClassCastException 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.
In general it is not a good idea to mix generics and arrays in Java, better use an ArrayList.
If you must use an array, the best way to handle this is to put the array creation (your example 2 or 3) in a separate method and annotate it with #SuppressWarnings("unchecked").
You can create generic array of map
Create list of map.
List<Map<String, ?>> myData = new ArrayList<Map<String, ?>>();
Initialize array.
Map<String,?>[]myDataArray=new HashMap[myData .size()];
Populate data in array from list.
myDataArray=myData.toArray(myDataArry);
Short answer appears to be that you really just can't.
See the following for a blog about it.
http://www.bloggingaboutjava.org/2006/01/java-generics-quirks/
One of the comments to the blog states that:
Actually, the engineers made the creation of such an Array illegal. So the creation of an array from generic Class fails. The Collection.toArray method followed by a Cast to the Array works at compile time.
This solves not the problem, that the ArrayStoreCheck can’t be done during Runtime, but you can create an Array of generics in this way.
As suggested by Bill the Lizard, you probably are better off using a
List<Map<String,Integer>>
I know its a bit late to reply but I found this workaround helpful for my case...Hope it helps!
Use an array of HashMap to store 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]);
}
myMaps = new HashMap<String, Integer>[10]();
So that's Wrong
Why not make a List of Maps instead of trying to make an array?
List<Map<String, Integer>> mymaps = new ArrayList<Map<String, Integer>>(count);

Categories