Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objects from ArrayList to Arrays

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;
}
like image 205
simonkaspers1 Avatar asked Apr 20 '26 17:04

simonkaspers1


1 Answers

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.

like image 124
Radiodef Avatar answered Apr 22 '26 05:04

Radiodef