I am trying do something like this:-
public static ArrayList<myObject>[] a = new ArrayList<myObject>[2];
myObject is a class. I am getting this error:- Generic array creation (arrow is pointing to new.)
You can't have arrays of generic classes. Java simply doesn't support it.
You should consider using a collection instead of an array. For instance,
public static ArrayList<List<MyObject>> a = new ArrayList<List<MyObject>();
Another "workaround" is to create an auxilliary class like this
class MyObjectArrayList extends ArrayList<MyObject> { }
and then create an array of MyObjectArrayList.
Here is a good article on why this is not allowed in the language. The article gives the following example of what could happen if it was allowed:
List<String>[] lsa = new List<String>[10]; // illegal
Object[] oa = lsa; // OK because List<String> is a subtype of Object
List<Integer> li = new ArrayList<Integer>();
li.add(new Integer(3));
oa[0] = li;
String s = lsa[0].get(0);
There is a easier way to create generic arrays than using List.
First, let
public static ArrayList<myObject>[] a = new ArrayList[2];
Then initialize
for(int i = 0; i < a.length; i++) {
a[i] = new ArrayList<myObject>();
}
You can do
public static ArrayList<myObject>[] a = (ArrayList<myObject>[])new ArrayList<?>[2];
or
public static ArrayList<myObject>[] a = (ArrayList<myObject>[])new ArrayList[2];
(The former is probably better.) Both will cause unchecked warnings, which you can pretty much ignore or suppress by using: #SuppressWarnings("unchecked")
if you are trying to declare an arraylist of your generic class you can try:
public static ArrayList<MyObject> a = new ArrayList<MyObject>();
this will give you an arraylist of myobject (size 10), or if u only need an arraylist of size 2 you can do:
public static ArrayList<MyObject> a = new ArrayList<MyObject>(2);
or you may be trying to make an arraylist of arraylists:
public static ArrayList<ArrayList<MyObject>> a = new ArrayList<ArrayList<MyObject>>();
although im not sure if the last this i said is correct...
It seems to me that you use the wrong type of parenthesis. The reason why you can't define an array of generic is type erasure.
Plus, declaration of you variable "a" is fragile, it should look this way:
List<myObject>[] a;
Do not use a concrete class when you can use an interface.
Related
I am trying do something like this:-
public static ArrayList<myObject>[] a = new ArrayList<myObject>[2];
myObject is a class. I am getting this error:- Generic array creation (arrow is pointing to new.)
You can't have arrays of generic classes. Java simply doesn't support it.
You should consider using a collection instead of an array. For instance,
public static ArrayList<List<MyObject>> a = new ArrayList<List<MyObject>();
Another "workaround" is to create an auxilliary class like this
class MyObjectArrayList extends ArrayList<MyObject> { }
and then create an array of MyObjectArrayList.
Here is a good article on why this is not allowed in the language. The article gives the following example of what could happen if it was allowed:
List<String>[] lsa = new List<String>[10]; // illegal
Object[] oa = lsa; // OK because List<String> is a subtype of Object
List<Integer> li = new ArrayList<Integer>();
li.add(new Integer(3));
oa[0] = li;
String s = lsa[0].get(0);
There is a easier way to create generic arrays than using List.
First, let
public static ArrayList<myObject>[] a = new ArrayList[2];
Then initialize
for(int i = 0; i < a.length; i++) {
a[i] = new ArrayList<myObject>();
}
You can do
public static ArrayList<myObject>[] a = (ArrayList<myObject>[])new ArrayList<?>[2];
or
public static ArrayList<myObject>[] a = (ArrayList<myObject>[])new ArrayList[2];
(The former is probably better.) Both will cause unchecked warnings, which you can pretty much ignore or suppress by using: #SuppressWarnings("unchecked")
if you are trying to declare an arraylist of your generic class you can try:
public static ArrayList<MyObject> a = new ArrayList<MyObject>();
this will give you an arraylist of myobject (size 10), or if u only need an arraylist of size 2 you can do:
public static ArrayList<MyObject> a = new ArrayList<MyObject>(2);
or you may be trying to make an arraylist of arraylists:
public static ArrayList<ArrayList<MyObject>> a = new ArrayList<ArrayList<MyObject>>();
although im not sure if the last this i said is correct...
It seems to me that you use the wrong type of parenthesis. The reason why you can't define an array of generic is type erasure.
Plus, declaration of you variable "a" is fragile, it should look this way:
List<myObject>[] a;
Do not use a concrete class when you can use an interface.
Can anybody tell me how to create an array-arraylist the right way ?!
.\File.java:5: warning: [unchecked] unchecked conversion
ArrayList<myObjectType> myParkingLotArray[] = new ArrayList[3];
^
required: ArrayList<Vehicle>[]
found: ArrayList[]
1 warning
I want an arry (or any other solution) which stores 3 arraylists. How to add objects to the arrylists would be nice to know too.
ParentArray
ChildArrayList1
ChildArrayList2
ChildArrayList3
Im happy for any Help
SOLUTION:
public class myClass {
ArrayList<myObjectType>[] myArryName= new ArrayList[3];
public void addLists() {
myArryName[0] = new ArrayList<myObjectType>();
myArryName[1] = new ArrayList<myObjectType>();
myArryName[2] = new ArrayList<myObjectType>();
}
}
The warning can be ignored or suppressed.
You can not create an Array of classes that use generic types - see here!
And there is no way to work around that error message. The compiler tells you: this ain't possible!
Instead - simply stay with one concept. There is no point of mixing arrays and Lists anyway. Just go for
List<List<Vehicle>> parents = new ArrayList<>();
And then
List<Vehicle> someChild = new ArrayList<>();
To finally do something like
parents.add(someChild);
You can do this with a cast
ArrayList<myObjectType>[] myParkingLotArray = (ArrayList<myObjectType>[]) new ArrayList[3];
However, I agree with GhostCat you should try to use arrays or lists but not mix them. a List<List<myObjectype>> would be better.
You cannot create arrays of parameterized types.
What you can do insteade is the following:
List [] arrayOfLists = new ArrayList[10];
arrayOfLists[0] = new ArrayList<Vehicle>();
but you can't be sure that all the lists will be List of the same type.
Otherwise you can use simply List of Lists in this way:
List<List<Vehicle>> listOfLists = new ArrayList<>();
List<Vehicle> list = new ArrayList<>();
listOfLists.add(list);
I need to wrap five classes: linkedlist, treeset, hashset, and two classes I created myself.
The wrapper and my two classes are all implementing the same interface.
this is the wrapper constructor:
private Collection <String> collection;
public CollectionFacadeSet(java.util.Collection<java.lang.String> collection){
this.collection = collection;
}
now, in another class I want to create a 5 cell array that each cell houses a different set.
This line is OK:
static CollectionFacadeSet[] setArray = new CollectionFacadeSet[5];
BUT, when I create a method that fills the cells:
private static void initializieArray(){
setArray[0] = CollectionFacadeSet(HashSet<String>);
}
it throws me an error:
Syntax error on token ">", Expression expected after this token
How to initiate each cell with a different set type?
The expression
setArray[0] = CollectionFacadeSet(HashSet<String>);
is invalid. You would need something like
setArray[0] = new CollectionFacadeSet(new HashSet<String>());
instead.
static CollectionFacadeSet[] setArray = new CollectionFacadeSet[5];
Array will store the objects of CollectionFacadeSet so use new
setArray[0] = new CollectionFacadeSet(new HashSet<String>());
Can a List<T> be initialized to contain a given number of nulls, where T is a type parameter of the class of which the list is a member? I sure can do it with a loop, but like to know whether it is possible without.
List<T> myList = new ArrayList<T>(numEls);
creates a list of the given capacity, but size 0, so myList.get(x) fails for all x, and so does, e.g. myList.set(numEls-1,null).
myList = Arrays.asList(new T[numEls]);
does not compile, and
myList = (List<T>) Arrays.asList(new Object[numEls]);
compiles in Eclipse (with an Unchecked cast warning), but not with javac.
Update: Thank you for the answers! However, I found another, quite short, solution close to my last attempt above, which compiles both in eclipse and with our automated build system: Cast the array, not the list!
myList = Arrays.asList((T[]) new Object[numEls]);
If you don't need to mutate the list...
List<T> result = Collections.nCopies(num, (T) null);
... or alternately
List<T> result = new ArrayList<T>(Collections.nCopies(num, (T) null));
You would need to use reflection to instantiate a backing array T[] using Array.newInstance():
public static <T> List<T> getListWithNulls(Class<T> componentType, int length) {
T[] array = (T[])Array.newInstance(componentType, length);
return new ArrayList<T>(Arrays.asList(array));
}
As you can see, this requires a reference to the Class<T> object representing the type of T:
List<String> strListWithNulls = getListWithNulls(String.class, 100);
Also make sure not to confuse the classes java.lang.reflect.Array and java.util.Arrays which are both used here.
Finally, note that reflection is going to be much slower than just using a loop.
Not really a solution, but you wanted to avoid a loop.
void fillNullList(List<T> list, count) {
if (count > 0) {
list.add(null);
fillNullList(list, count - 1);
}
}
Seriously, why do you want to avoid a loop? Probably, you want a solution with O(1) complexity and not a O(n) complexity solution regardless if a loop is used for not.
What you probably want is something like this....
final int maxSize = 50;
List<T> v = new Vector<T>() {{setSize(maxSize);}};
Vectors allow you to set a size, which fills them with null's.
I would just use a loop, its simpler and likely to be faster as well.
List<T> list =
while(list.size()<size) list.add(null);
Any other approach you use is likely to use a loop for you. If this is fine, just write your own method which hides the loop used.
new option with streams:
List resultColumn = IntStream.range(0, 10000).mapToObj(i -> null).collect(Collectors.toList());
Try this:
List<String> list = new ArrayList<String>(Arrays.asList(new String[100]));
for(String string : list){
System.out.println(string);
}
Well, you can write a hierarchy:
class Base<T>{
protected List<T> list;
public List<T> getList(){
return list;
}
}
class Child extends Base<String>{
public Child(){
list = new ArrayList<String>(Arrays.asList(new String[100]));
}
}
It can be used in the next way:
Base<String> base = new Child();
base.getList();
What I did was
MyClass[] array = {new MyClass(), new MyClass(), new MyClass(), new MyClass(), new ProfileSectionDTO(), new MyClass()};
List<MyClass> MyClassList = Arrays.asList(array);
Dirty, but working :)
if you want an ArrayList you can use reflection to cheat
ArrayList<T> myList = new ArrayList<T>(numEls);
Field f = ArrayList.class.getField("size");//cache this
f.setAccessible(true);
f.setInt(myList, numEls);
Why can't I create an array of List ?
List<String>[] nav = new List<String>[] { new ArrayList<String>() };
Eclipse says "Cannot create a generic array of List"
or
ArrayList<String>[] nav = new ArrayList<String>[] { new ArrayList<String>() };
Eclipse says "Cannot create a generic array of ArrayList"
or
List<String>[] getListsOfStrings() {
List<String> groupA = new ArrayList<String>();
List<String> groupB = new ArrayList<String>();
return new List<String>[] { groupA, groupB };
}
But I can do this:
List[] getLists() {
return new List[] { new ArrayList(), new ArrayList() };
}
Eclipse says that List and ArrayList are raw types but it compiles...
Seems pretty simple, why won't it work?
Well, generics tutorial give the answer to your question.
The component type of an array object
may not be a type variable or a
parameterized type, unless it is an
(unbounded) wildcard type.You can
declare array types whose element type
is a type variable or a parameterized
type, but not array objects.
This is
annoying, to be sure. This restriction
is necessary to avoid situations like:
// Not really allowed.
List<String>[] lsa = new List<String>[10];
Object o = lsa;
Object[] oa = (Object[]) o;
List<Integer> li = new ArrayList<Integer>();
li.add(new Integer(3));
// Unsound, but passes run time store check
oa[1] = li;
// Run-time error: ClassCastException.
String s = lsa[1].get(0);
If arrays of parameterized type were
allowed, the previous example would
compile without any unchecked
warnings, and yet fail at run-time.
We've had type-safety as a primary
design goal of generics.
You can't create arrays of generic types, generally.
The reason is that the JVM has no way to check that only the right objects are put into it (with ArrayStoreExceptions), since the difference between List<String> and List<Integer> are nonexistent at runtime.
Of course, you can trick the compiler by using the raw type List or the unbound wildcard type List<?>, and then cast it (with a unchecked cast) to List<String>. But then it is your responsibility to put only List<String> in it and no other lists.
No exact answer, but a tip:
Last example has a raw type warning because you omitted the typization of the list; it is generally a better (type safe) approach to specify which object types are contained in the list, which you already did in the previous examples (List<String> instead of List).
Using arrays is not best practice, since their use contains errors most times; Using Collection classes (List, Set, Map,...) enables use of typization and of convenient methods for handling their content; just take a look at the static methods of the Collections class.
Thus, just use the example of the previous answer.
Another solution is to extend LinkedList<String> (or ArrayList<String>, etc.), then create an array of the subclass.
private static class StringList extends LinkedList<String> {}
public static void main(String[] args)
{
StringList[] strings = new StringList[2];
strings[0] = new StringList();
strings[1] = new StringList();
strings[0].add("Test 1");
strings[0].add("Test 2");
strings[1].add("Test 3");
strings[1].add("Test 4");
System.out.println(strings[0]);
System.out.println(strings[1]);
}