Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Convert Generic LinkedList to Generic Array

Tags:

java

generics

So for starters lets say that I have a LinkedList<String>,

I can easily convert it to an array via toArray(). i.e.

LinkedList<String> strList = new LinkedList<String>();
String[] strArray = strList.toArray(new String[0]);

But Lets say I have a LinkedList<T> Then I the following code:

LinkedList<T> tList = new LinkedList<T>();
T[] strArray = tList.toArray(new T[0]);

I get the Cannot create a generic array of T error message.

How can I get around this?

Specifically in my class I have LinkedList<AbstractNode<T>> nodes, and I am trying to implement a getAll() method that returns all the nodes as an Array.
Thanks!

Note Péter Török's answer provides the correct answer to my problem, but for me simply returning an ArrayList instead of [] as Bar mentioned, ended up smoothing my code out a lot.
Note2 after looking at my code a bit more i'm not even sure if any conversion was necessary to begin with, LinkedList was fine for what I was trying to do... :-/

like image 492
Kenny Cason Avatar asked Sep 01 '10 12:09

Kenny Cason


People also ask

Can you create an array of generic type?

No, we cannot create an array of generic type objects if you try to do so, a compile time error is generated.

Can you make a generic array in Java?

Generic array creation is not allowed in Java.

Can you make an array of linked lists in Java?

A linked list is a sequence of data structures, which are connected together via links. To create an array of linked lists, create required linked lists and, create an array of objects with them.


2 Answers

A workaround which is used in the class library would be (using an unchecked cast)

public <T> T[] toArray(List<T> list, T[] a) {
  if (a.length < list.size()) {
    a = (T[])java.lang.reflect.Array.newInstance(
        a.getClass().getComponentType(), list.size()));
  }
  return list.toArray(a);
}

or, with a Class parameter instead of an array:

public <T> T[] toArray(List<T> list, Class<T> k) {
     return list.toArray(
          (T[])java.lang.reflect.Array.newInstance(k, list.size()));
}

From Java Generics and Collections, chapters 6.4-5.

Inability to create generic arrays is one of the most serious restrictions in Java. Because it is so annoying, it is worth reiterating the reason it occurs: generic arrays are problematic because generics are implemented via erasure, but erasure is beneficial because it eases evolution.

The best workaround is to use ArrayList or some other class from the Collections Framework in preference to an array. We discussed the tradeoffs between collection classes and arrays in Section 2.5, and we noted that in many cases collections are preferable to arrays: because they catch more errors at compile time, because they provide more operations, and because they offer more flexibility in representation. By far, the best solution to the problems offered by arrays is to "just say no": use collections in preference to arrays.

Sometimes this won't work, because you need an array for reasons of compatibility or efficiency. Examples of this occur in the Collections Framework: for compatibility, the method toArray converts a collection to an array [...]

[...] a naïve method to convert a collection to an array will not work. The first fix we might try is to add an unchecked cast, but we will see shortly that this leads to even more perplexing problems. The correct fix will require us to resort to reflection.

like image 123
Péter Török Avatar answered Oct 14 '22 07:10

Péter Török


Since Java generic is really replaceing your T with type object and casting to concrete type resolved at compilation, there is possible to create List<T>, but not T[]. (First one will be list of objects, second one is unknown) Well reflection allows you to do many ugly hacks. You can use them. Personally I use them only if there is no other ways to do something. I don't like runtime errors.

But my question is: Do you REALLY needs T[], why don't you use ArrayList<T> instead?

like image 1
Bart Avatar answered Oct 14 '22 05:10

Bart