I am fetching some information from a database. I have a method the makes ArrayList of objects of the given tables. Like Tools, Customer and etc.
I was wondering if it was possible to make a small helping-method that takes in an ArrayList and return a list(Tool[]) dynamic of the type of content or do i have to make method per type of objects? Is there a more dynamic way to solve it?
This is not the method, but an example of a method for a given type of objects, dont bother about compiling and logic in the code, its just for the example:
public Verktoy[] ToolsArray(ArrayList<Verktoy> b){
Verktoy[] a = new Verktoy[b.size()];
for(int i = 0; i<b.size(); i++){
a[i] = b.get(i);
}
return a;
}
So basically the method signature you want is like this:
public static <E> E[] toArray(List<E> list);
And usage would be:
List<String> strList = new ArrayList<String>();
String[] strArr = toArray(strList);
List<Integer> intList = new ArrayList<Integer>();
Integer[] intArr = toArray(intList);
Now, as mentioned, List already defines a method that does this except it's not really generic. You have to give it an array to copy in to or use Object[].
List<String> strList = new ArrayList<String>();
Object[] objArr = strList.toArray();
String[] strArr = strList.toArray(new String[strList.size()]);
I assume neither of those are what you are wanting. Unfortunately, there is not a way to do exactly what you are asking because you cannot create an array generically in Java. Going back to the method:
public static <E> E[] toArray(List<E> list) {
E[] arr = new E[list.size()]; // doesn't compile
return list.toArray(arr);
}
The problem being that E is erased so that is not compilable Java code. <E> doesn't exist at run time to be able to do new E.
So the closest you can get is like this:
public static <E> E[] toArray(List<E> list, Class<E> e) {
@SuppressWarnings("unchecked")
final E[] arr = (E[])Array.newInstance(e, list.size());
return list.toArray(arr);
}
But that is not really any more convenient to use:
List<String> strList = new ArrayList<String>();
String[] strArr = toArray(strList, String.class);
There is another interesting approach which is to extend the ArrayList and add this functionality to it. But you still need the Class<E> object. You'd do it like this:
import java.util.Arraylist;
import java.util.Objects;
import java.lang.reflect.Array;
public class TypedList<E> extends ArrayList<E> {
private final Class<E> e;
public TypedList(Class<E> e) {
this.e = Objects.requireNonNull(e);
}
@Override
public E[] toArray() {
@SuppressWarnings("unchecked")
final E[] arr = (E[])Array.newInstance(e, size());
return toArray(arr);
}
}
This lets you specify the Class<E> at the very beginning and later you can call toArray with no arguments, e.g.:
TypedList<String> strList = new TypedList<String>(String.class);
String[] strArray = strList.toArray();
What I'd recommend is to steer away from trying to use arrays generically. They are not good for this type of thing.
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