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.
If the list is final can it be copied to another list so if we make changes in new list the original one doesn't get affected ?
public class Solution {
// DO NOT MODIFY THE LIST
public int maximumGap(final List<Integer> a) {
if(a.size()<2)return 0;
List<Integer> c=new List<Integer>(a);
Collections.sort(c);
return c.get(c.size()-1)-c.get(c.size()-2);
}
}
The compiler must be stating
Cannot instantiate the type List
since List is an interface and not an class.
A class must be given like in
List<Integer> c = new ArrayList<>(a);
If you copy a list into another one, then they are independent regardless of the final keyword.
I am creating a list data structure and am having trouble with the generics syntax for actually using it. All I am trying to do is create an instance of ArrayLinearList<String> and of size 2 and put some strings in it. I have been trying to figure out why setting the first slot to "one" is not correct. This is the error and my code snippet.
myList[0] = "one";
The error message is: error: incompatible types: String cannot be converted to ArrayLinearList<String>
public class ArrayLinearList<E> implements LinearListADT<E> {
private Object[] array;
int currentSize = 0;
//Constructor (no arguments)
public ArrayLinearList() {
currentSize = 2;
// array = (ArrayLinearList[]) new Object[2]; //Start with a container of size 2
array = new Object[2];
}
public static void main(String[] var0) {
ArrayLinearList<String>[] myList;
myList = new ArrayLinearList[2];
myList[0] = "one";
}
}
I am having quite a bit of trouble with the syntax with using generics in java. In my mind I have an array of size 2 where I am going to be placing strings. I will add more methods later but I want to understand why my current syntax is incorrect for placing this string in the array.
Here:
ArrayLinearList<String>[] myList;
you define an array that holds ArrayLinearList<String> elements, not Strings, this is why you get the error message.
Your code here
ArrayLinearList<String>[] myList;
myList = new ArrayLinearList[2];//you have defining array myList of type ArrayLinearList
myList[0] = "one";//you are trying to store String to array which can hold ArrayLinearList
Here ArrayLinearList<String> means that your list will hold values of type String (provided we define it correctly in the code). But ArrayLinearList<String>[] will hold only reference of type ArrayLinearList and not String itself.
You need to use
myList.array[0] = "one";
Because myList is not an array. It's an object which you use to store an array within.
I would like to use simpleJdbcInsert class and executeBatch method
public int[] executeBatch(Map<String,Object>[] batch)
http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/jdbc/core/simple/SimpleJdbcInsert.html
So I need to pass an array of Map<String,Object> as parameter. How to create such an array?
What I tried is
Map<String, Object>[] myArray = new HashMap<String, Object>[10]
It is error: Cannot create generic array of Map<String, Object>
A List<Map<String, Object>> would be easier, but I guess I need an array. So how to create an array of Map<String, Object> ?
Thanks
Because of how generics in Java work, you cannot directly create an array of a generic type (such as Map<String, Object>[]). Instead, you create an array of the raw type (Map[]) and cast it to Map<String, Object>[]. This will cause an unavoidable (but suppressible) compiler warning.
This should work for what you need:
Map<String, Object>[] myArray = (Map<String, Object>[]) new Map[10];
You may want to annotate the method this occurs in with #SuppressWarnings("unchecked"), to prevent the warning from being shown.
You can create generic array of map.
Create a list of maps.
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(myDataArray);
I have had some difficulty with this, but I have figured out a few things that I will share as simply as possible.
My experience with generics is limited to collections, so I use them in the class definitions, such as:
public class CircularArray<E> {
which contains the data member:
private E[] data;
But you can't make and array of type generic, so it has the method:
#SuppressWarnings("unchecked")
private E[] newArray(int size)
{
return (E[]) new Object[size]; //Create an array of Objects then cast it as E[]
}
In the constructor:
data = newArray(INITIAL_CAPACITY); //Done for reusability
This works for generic generics, but I needed a list that could be sorted: a list of Comparables.
public class SortedCircularArray<E extends Comparable<E>> {
//any E that implements Comparable or extends a Comparable class
which contains the data member:
private E[] data;
But our new class throws java.lang.ClassCastException:
#SuppressWarnings("unchecked")
private E[] newArray(int size)
{
//Old: return (E[]) new Object[size]; //Create an array of Objects then cast it as E[]
return (E[]) new Comparable[size]; //A comparable is an object, but the converse may not be
}
In the constructor everything is the same:
data = newArray(INITIAL_CAPACITY); //Done for reusability
I hope this helps and I hope our more experienced users will correct me if I've made mistakes.
From Oracle tutorial [sic]:
You cannot create arrays of parameterized types. For example, the following code does not compile:
List<Integer>[] arrayOfLists = new List<Integer>[2]; // compile-time error
The following code illustrates what happens when different types are inserted into an array:
Object[] strings = new String[2];
strings[0] = "hi"; // OK
strings[1] = 100; // An ArrayStoreException is thrown.
If you try the same thing with a generic list, there would be a problem:
Object[] stringLists = new List<String>[]; // compiler error, but pretend it's allowed
stringLists[0] = new ArrayList<String>(); // OK
stringLists[1] = new ArrayList<Integer>(); // An ArrayStoreException should be thrown,
// but the runtime can't detect it.
If arrays of parameterized lists were allowed, the previous code would fail to throw the desired ArrayStoreException.
To me, it sounds very weak. I think that any programmer with a sufficient understanding of generics, would be perfectly fine, and even expect, that the ArrayStoredException is not thrown in such case.
Even more, most programmers will simply do:
List<Integer> arrayOfLists = (List<Integer>) new List[2];
which will put them in exactly the same risk of ArrayStoreException not thrown.
As far my knowledge
Frist try to create an array of java.lang.Object and then cast to Generic type T
Example:
class Example<DataType>{
public DataType array = (DataType[]) new Object[5] ;
}
In this way, you can create an array of generic datatype
#SuppressWarnings("unchecked")
private Map<String,?>[] newArray(int n) {
return new Map[n];
}
using with a Stream of Map<String,?>:
sql.executeBatch(myStream.toArray(this::newArray));
using with a List of Map<String,?>:
sql.executeBatch(myList.toArray(newArray(0));
NOTE: the SuppressWarnings trick is actively used in JDK src - https://github.com/AdoptOpenJDK/openjdk-jdk14/blob/master/src/java.base/share/classes/java/util/ArrayList.java#L395:L404
Credits to: #JonathanCallen
Can somebody please explain me why I can't cast List<> to ArrayList<> with first approach and I do with second one? Thank you.
First approach:
ArrayList<Task> tmp = ((ArrayList<Task>)mTrackytAdapter.getAllTasks(token));
Second approach:
ArrayList<Task> tmp = new ArrayList<Task>(mTrackytAdapter.getAllTasks(token));
When you do the second one, you're making a new arraylist, you're not trying to pretend the other list is an arraylist.
I mean, what if the original list is implemented as a linkedlist, or some custom list? You won't know. The second approach is preferred if you really need to make an arraylist from the result. But you can just leave it as a list, that's one of the best advantages of using Interfaces!
When you are using second approach you are initializing arraylist with its predefined values.
Like generally we do
**ArrayList listofStrings = new ArrayList<>();
**
Let's say you have an array with values, now you want to convert this array into arraylist.
you need to first get the list from the array using Arrays utils.
Because the ArrayList is concrete type that implement List interface. It is not guaranteed that method asList, will return this type of implementation.
List<String> listofOptions = (List<String>) Arrays.asList(options);
then you can user constructoru of an arraylist to instantiate with predefined values.
ArrayList<String> arrlistofOptions = new ArrayList<String>(list);
So your second approach is working that you have passed values which will intantiate arraylist with the list elements.
More over
ArrayList that is returned from Arrays.asList is not an actual arraylist, it is just a wrapper which doesnt allows any modification in the list.
If you try to add or remove over Arrays.asList it will give you
UnsupportedOperationException
Try running the following code:
List<String> listOfString = Arrays.asList("Hello", "World");
ArrayList<String> arrayListOfString = new ArrayList(listOfString);
System.out.println(listOfString.getClass());
System.out.println(arrayListOfString.getClass());
You'll get the following result:
class java.util.Arrays$ArrayList
class java.util.ArrayList
So, that means they're 2 different classes that aren't extending each other. java.util.Arrays$ArrayList signifies the private class named ArrayList (inner class of Arrays class) and java.util.ArrayList signifies the public class named ArrayList. Thus, casting from java.util.Arrays$ArrayList to java.util.ArrayList and vice versa are irrelevant/not available.
The second approach is clearly wrong if you want to cast. It instantiate a new ArrayList.
However the first approach should work just fine, if and only if getAllTasks return an ArrayList.
It is really needed for you to have an ArrayList ? isn't the List interface enough ? What you are doing can leads to Runtime Exception if the type isn't correct.
If getAllTasks() return an ArrayList you should change the return type in the class definition and then you won't need a cast and if it's returning something else, you can't cast to ArrayList.
Just try this :
ArrayList<SomeClass> arrayList;
public SomeConstructor(List<SomeClass> listData) {
arrayList.addAll(listData);
}
You can cast List<> to ArrayList<> if you understand what you doing. Java compiler won't block it.
But:
It's bad practice to casting parent type to child type (or interface to implementation type) without checking.
This way better:
if (list instanceof ArrayList<Task>) {
ArrayList<Task> arraylist = (ArrayList<Task>) list;
}
Maybe you don't need implementation type as reference. Look SonarQube warning https://sbforge.org/sonar/rules/show/squid:S1319. You can avoid this casting in the most cases.
You can use Guava method:
ArrayList<Task> arraylist = Lists.newArrayList(list);
The first approach is trying to cast the list but this would work only if the List<> were an ArrayList<>. That is not the case. So you need the second approach, that is building a new ArrayList<> with the elements of the List<>
Because in the first one , you're trying to convert a collection to an ArrayList.
In the 2nd one , you just use the built in constructor of ArrayList
May be:
ArrayList<ServiceModel> services = new ArrayList<>(parking.getServices());
intent.putExtra("servicios",services);
import java.util.List;
import java.util.Arrays;
import java.util.*;
public class Merge
{
public static void main(String[] args) {
// This is normal way
// List<Integer> l1 = new ArrayList<Integer>(); l1.add(2); l1.add(5); l1.add(10); l1.add(22);
// List<Integer> l2 = new ArrayList<Integer>(); l2.add(3); l2.add(8); l2.add(15);
//Array.asList only have the list interface, but ArrayList is inherited from List Interface with few more property like ArrayList.remove()
List<Integer> templ1 = Arrays.asList(2,5,10,22);
List<Integer> templ2 = Arrays.asList(3,8,12);
//So creation of ArrayList with the given list is required, then only ArrayList.remove function works.
List<Integer> l1 = new ArrayList<Integer>(templ1);
List<Integer> l2 = new ArrayList<Integer>(templ2);
List<Integer> l3 = new ArrayList<Integer>();
Iterator itr1 = l1.iterator();
while(itr1.hasNext()){
int x = (Integer) itr1.next();
Iterator itr2 = l2.iterator();
while(itr2.hasNext()) {
int y = (Integer) itr2.next();
if(x < y) {
l3.add(x);
break;
}
else{
l3.add(y);
itr2.remove();
}
}
}
Iterator it = l1.iterator();
while (it.hasNext()){
int k = (Integer) it.next();
if (l3.contains(k)){
continue;
}
else{
l3.add(k);
System.out.println(k);
}
}
Iterator itr2 = l2.iterator();
while (itr2.hasNext()){
int k = (Integer) itr2.next();
l3.add(k);
}
System.out.println(l3);
}
}