2010-09-01 3 views
12

Donc, pour commencer lets dire que j'ai un LinkedList<String>,Java Convert générique LinkedList to Array Generic

je peux facilement le convertir en un tableau via toArray(). à savoir

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

Mais Disons que j'ai un LinkedList<T> Je le code suivant:

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

Je reçois le Impossible de créer un tableau générique de message d'erreur T.

Comment puis-je contourner le problème?

Spécifiquement dans ma classe j'ai LinkedList<AbstractNode<T>> nodes, et j'essaie d'implémenter une méthode getAll() qui retourne tous les nœuds comme un tableau.
Merci!

Note La réponse de Péter Török fournit la bonne réponse à mon problème, mais pour moi, simplement renvoyer un ArrayList au lieu de [] comme Bar mentionné, a fini par lisser mon code beaucoup.
Note2 après avoir regardé mon code un peu plus je ne suis même pas sûr que la conversion était nécessaire pour commencer, LinkedList était bien pour ce que je voulais faire ...: -/

Répondre

13

Une solution qui est utilisé dans la bibliothèque de classes serait (avec un casting sans contrôle)

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); 
} 

ou, avec un paramètre Class au lieu d'un tableau:

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

de Java Generics and Collections, chapitres 6.4-5.

L'incapacité de créer des tableaux génériques est l'une des restrictions les plus sérieuses de Java. Parce que c'est tellement ennuyeux, il vaut la peine de réitérer la raison pour laquelle cela se produit: les tableaux génériques sont problématiques parce que les génériques sont implémentés par effacement, mais l'effacement est bénéfique car cela facilite l'évolution.

La meilleure solution consiste à utiliser ArrayList ou une autre classe de Collections Framework de préférence à un tableau. Nous avons discuté des compromis entre les classes de collection et les tableaux dans la section 2.5, et nous avons noté que dans de nombreux cas, les collections sont préférables aux tableaux: parce qu'elles attrapent plus d'erreurs à la compilation, parce qu'elles offrent plus d'opérations. De loin, la meilleure solution aux problèmes offerts par les tableaux est de «dire non»: utiliser les collections de préférence aux tableaux. Parfois, cela ne fonctionnera pas, car vous avez besoin d'une matrice pour des raisons de compatibilité ou d'efficacité. Des exemples de cela se produisent dans le cadre Collections: pour la compatibilité, la méthode toArray convertit une collection en un tableau [...]

[...] une méthode naïve pour convertir une collection en un tableau ne fonctionnera pas. La première solution que nous pourrions essayer est d'ajouter une distribution non cochée, mais nous verrons bientôt que cela conduit à des problèmes encore plus complexes. La solution correcte nous obligera à recourir à la réflexion.

+0

il doit y avoir un moyen sans utiliser la réflexion et ce qui est "a" dans ce bloc de code a.getClass(). GetComponentType() –

+2

@krmby: non, il n'y a pas de telle manière. Les génériques sont implémentés en utilisant l'effacement en Java, ce qui signifie que le type de temps de compilation n'est pas connu, donc vous pouvez seulement "tricher" en obtenant le type d'exécution, ce qui signifie utiliser la réflexion. Vous pourriez passer une 'Classe ' et l'utiliser dans 'newInstance()' mais cela serait toujours une réflexion. –

+0

@krmby, malheureusement il n'y en a pas. Veuillez vérifier le code mis à jour. –

1

Depuis Java générique est vraiment replaceing votre T avec le type object et coulée de béton de type résolu à la compilation, il est possible de créer List<T>, mais pas T[]. (Le premier sera la liste des objets, le second est inconnu) La réflexion vous permet de faire de nombreux hacks. Vous pouvez les utiliser. Personnellement, je ne les utilise que s'il n'y a pas d'autres moyens de faire quelque chose. Je n'aime pas les erreurs d'exécution. Mais ma question est: Avez-vous vraiment besoin de T[], pourquoi n'utilisez-vous pas ArrayList<T> à la place?

+0

Intéressant, je donnerai 'ArrayList ' un spin –

+0

Il était aussi facile que 'return new ArrayList > (nœuds); 'Merci, cela a rendu mon code beaucoup plus propre –

+0

Je devais changer les réponses sélectionnées si La réponse de Peter était techniquement correcte, mais merci pour le travail! –