1

I want to create a static array from a dynamic array of whatever generic type the dynamic array was. I saw List#toArray() which returns Object[] and it doesn't use generics. Is it just safe to cast it to T[] or does the entire array have to be instantiated from the type of class using it?

I went on to try and create my own method in case java didn't provide one but, I got stuck with a compile errors

public static <T> T[] toArray(List<T> list)
{
    T[] li = (T[]) Array.newInstance(T.class, list.size());
    int index = 0;
    for(T obj : list)
    {
        li[index++] = obj;
    }
    return li;
}
3
  • 5
    Try to avoid mixing Arrays and generics. Arrays are covariant and retained, while Generics are invariant and erased. This is a recipe for trouble. Even ArrayList uses an Object[] as its backing structure and only casts when elements are returned. --- Due to the erased nature of Generics, their type information is only available at compile-time, which is the reason why you cannot access T.class at runtime. Commented Feb 9, 2020 at 7:09
  • also note that above code using newInstance() is not better than toArray() - both need casting Commented Feb 9, 2020 at 8:04
  • If it were possible to do this, don't you think it would have been included in the collections API? Commented Feb 9, 2020 at 8:34

3 Answers 3

2

First of all, you don't need that method. You can use:

List<String> list = new ArrayList<>();
list.add("ff");
list.add("bb");
String[] array = list.toArray (new String[list.size ()]);

In order for your method to work, you have to pass the Class of the generic type parameter:

public static <T> T[] toArray(List<T> list, Class<T> clazz)
{
    T[] li = (T[]) Array.newInstance(clazz, list.size());
    int index = 0;
    for(T obj : list)
    {
        li[index++] = obj;
    }
    return li;
}

Then you can call the method with:

String[] array = toArray(list, String.class);
Sign up to request clarification or add additional context in comments.

2 Comments

is it just safe to just cast to T[] using ArrayList#toArray()? Will it accept other objects that are not it's casted type?
@nullsector76 no. You'll get a ClassCastException, since ArrayList#toArray() returns an Object[], which can't be cast to T[]. (unless T is also Object)
1

The method proposed by Eran doesn't work if you have a generic element type, because you can't get a Class<List<T>>, say.

Instead, pass an IntFunction<T[]>:

public static <T> T[] toArray(List<? extends T> list, IntFunction<T[]> arraySupplier)
{
    T[] li = arraySupplier.get(list.size());
    int index = 0;
    for(T obj : list)
    {
        li[index++] = obj;
    }
    return li;
}

Or, easier, use streams:

return list.stream().toArray(arraySupplier);

Then call like:

String[] array = toArray(list, String[]::new);

List<List<String>> listOfLists = ...
List<?>[] arrayOfLists = toArray(listOfLists, List<?>::new);

Notice that whilst this does support generic array elements, you can only create arrays with a reified element type, so your array type has to be List<?>[]; it still can't be List<String>[].

Comments

0

If your business requirement/Use Case requires an array to be no longer dynamic then you should first create a static array of size equal to your size of dynamic array.

   ArrayList<Integer> al = [............] // assuming that ArrayList named al is having some data
   int[] arr = new int[al.size()];

   // from here you can use a for loop and initialize your static array
   for(int i=0; i<arr.length;i++) {
       arr[i] = (int) al.get(i); // Unboxing will also be done but still you can type cast to be on safe side
   }
   // Now you can de-reference the ArrayList object and call garbage collection which will wipe it out of the Heap Memory of your JVM.
   al = null; // de-referencing the object by making the reference variable null
   System.gc(); // GC happens periodically but to boost performance you can explicitly call it right away.

You can create a method accepting the list of objects and can handle all sorts of arrays using instanceof operator.

1 Comment

but new will not work with generic type T (main point of question - it is no problem to create an array at runtime if the type i known at compile time)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.