Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert a generic list to an array

Tags:

java

generics

I have searched for this, but unfortunately, I don't get the correct answer.

class Helper {
    public static <T> T[] toArray(List<T> list) {
        T[] array = (T[]) new Object[list.size()];
        for (int i = 0; i < list.size(); i++) {
            array[i] = list.get(i);
        }
        return array;
    }
}

Test it:

public static void main(String[] args) {
    List<String> list = new ArrayList<String>();
    list.add("abc");
    String[] array = toArray(list);
    System.out.println(array);
}

But there is an error thrown:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
at test.Helper.main(Helper.java:30)

How to solve this?


UPDATE

I want this method, because sometimes, the type in my code is too long:

newEntries.toArray(new IClasspathEntry[0])

I'd hope to call:

toArray(newEntries)

FINALLY

It seems impossible to create such a method, thank you all very much!

like image 504
Freewind Avatar asked Jun 29 '11 14:06

Freewind


People also ask

Can you convert an ArrayList to an array?

To convert ArrayList to array in Java, we can use the toArray(T[] a) method of the ArrayList class. It will return an array containing all of the elements in this list in the proper order (from first to last element.) Here's a short example to convert an ArrayList of integers, numbersList , to int array.

Can a generic be an array?

Considerations When Using Generic Arrays Specifically, arrays store and check type information at runtime. Generics, however, check for type errors at compile-time and don't have type information at runtime. Java's syntax suggests we might be able to create a new generic array: T[] elements = new T[size];

Is it possible to have a generic ArrayList of Java arrays?

Notice that we can't use generics while creating the array because java doesn't support generic array. So if we try to use below code, it will produce compile time error as “Cannot create a generic array of List<String>”.


4 Answers

This is due to type erasure. The generics are removed in compilation, thus the Helper.toArray will be compiled into returning an Object[].

For this particular case, I suggest you use List.toArray(T[]).

String[] array = list.toArray(new String[list.size()]); 
like image 155
aioobe Avatar answered Oct 09 '22 00:10

aioobe


You can just call list.toArray(T[] array) and not have to worry about implementing it yourself, but as aioobe said, you can't create an array of a generic type due to type erasure. If you need that type back, you need to create a typed instance yourself and pass it in.

like image 25
Reverend Gonzo Avatar answered Oct 08 '22 23:10

Reverend Gonzo


If you want to produce your method through brute force, and you can guarantee that you'll only call the method with certain restrictions, you can use reflection:

public static <T> T[] toArray(List<T> list) {
    T[] toR = (T[]) java.lang.reflect.Array.newInstance(list.get(0)
                                           .getClass(), list.size());
    for (int i = 0; i < list.size(); i++) {
        toR[i] = list.get(i);
    }
    return toR;
}

This approach has problems. As list can store subtypes of T, treating the first element of the list as the representative type will produce a casting exception if your first element is a subtype. This means that T can't be an interface. Also, if your list is empty, you'll get an index out of bounds exception.

This should only be used if you only plan to call the method where the first element of the list matches the Generic type of the list. Using the provided toArray method is much more robust, as the argument provided tells what type of array you want returned.

like image 42
Atreys Avatar answered Oct 08 '22 23:10

Atreys


You can't instantiate a Generic type like you did here:

 T[] array = (T[]) new Object[list.size()];

As, if T is bounded to a type, you're typecasting the new Object array to a bounded type T. I would suggest using List.toArray(T[]) method instead.

like image 42
Buhake Sindi Avatar answered Oct 08 '22 23:10

Buhake Sindi