3

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;
}
simonkaspers1
  • 616
  • 4
  • 16
  • Possible duplicate: http://stackoverflow.com/questions/7969023/from-arraylist-to-array – csvan Apr 03 '14 at 20:20
  • not duplicate, have search and seen that one :) – simonkaspers1 Apr 03 '14 at 20:33
  • *"return a list(Tool[])"* Can you please clarify this part, I don't know what `list(Tool[])` is supposed to convey. – Radiodef Apr 03 '14 at 20:33
  • Its a silly way to give a example on a list, or array if you like, the type of objects is not given, so the array may contain different types @Radiodef – simonkaspers1 Apr 03 '14 at 20:42
  • You need to be more specific than that. You want to convert a List to an array but generically? Possibly show us an example of the helper method for a single type of object. – Radiodef Apr 03 '14 at 20:43
  • @radiodef, have given an small example of the type of code, just some basic ArrayList ---> Array-method – simonkaspers1 Apr 03 '14 at 20:51

3 Answers3

1

http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#toArray(T[])

This is build into ArrayList. There's a version that returns an array of Object and one that returns the correct type.

Andreas
  • 5,393
  • 9
  • 44
  • 53
bstempi
  • 2,023
  • 1
  • 15
  • 27
1

Yes, you can - this is the purpose of generics. You can do something like:

List<T> list = new ArrayList<T>();
T [] elements = list.toArray(new T[list.size()]);
ucsunil
  • 7,378
  • 1
  • 27
  • 32
1

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.

Radiodef
  • 37,180
  • 14
  • 90
  • 125