2017-05-17 2 views
0

J'ai du mal à trouver cela partout si c'est un problème courant, mais je fais face à ce qui est essentiellement un problème de type cascade. Je veux faire quelque chose comme ça, mais je ne peux pas instancier le tableau générique de cette façon. Où le getNodes() retourne le contenu des nœuds, pas les nœuds eux-mêmes, mais je ne peux pas comprendre comment.Déclarations de type générique en cascade en Java

Je pensais que le générique de Node étant défini par le générique Graph signifierait que la classe Node a toujours le même type que la classe Graph. N'est-ce pas le cas?

La classe Node ressemble

public class Node<E> { 

    private LinkedList<Edge> edges; 
    private E obj; 

    public E getObject() { 
     return obj; 
    } 

    // other useful stuff 
} 

Merci pour toute aide!

EDIT: tout ce qui est nécessaire maintenant est de rendre le tableau retourné du bon type. Existe-t-il un moyen d'obtenir un tableau à partir d'un ArrayList qui a une affectation de type générique?

+0

Si c'était possible, ne pensez-vous pas que 'ArrayList' l'aurait fait? – shmosel

+0

Ceci est une version générique du problème que j'ai. À l'heure actuelle, il est inutile de créer la classe Custom car elle n'ajoute aucune nouvelle fonctionnalité, mais mon code actuel le fait. Pour autant que je sache, je ne peux pas trouver un moyen de contourner ce type de mise en œuvre. – user3785637

+2

Faites simplement ce que 'ArrayList' fait:' public T [] getThings (T [] a) {retourne things.toArray (a); } ' – shmosel

Répondre

1

Quelqu'un d'autre est venu avec une réponse qui ne fonctionne pas, mais m'a donné une idée qui a fini par travailler, mais ils ont mis aussi en la section des commentaires de la question, donc je vais réitérer ici et répondre à ma propre question.

Ce code fonctionne pour résoudre le problème. J'ai plus ou moins levé la logique du code source ArrayList pour leur fonction toArray(E[] a) (avec une partie de la viande qui a été coupée bien sûr).

@SuppressWarnings("unchecked") 
public E[] getNodes(E[] a) { 
    int size = nodes.size(); 
    // creates an empty array of the right size and type 
    E[] arr =(E[]) java.lang.reflect.Array 
      .newInstance(a.getClass().getComponentType(), size); 
    // fills that array with the correct data 
    for (int i = 0; i < size; i++) 
     arr[i] = nodes.get(i).getObject(); 
    return arr; 
} 

Regardez le code source ArrayList afin de voir une logique qui va plus loin et accomplit la même tâche d'une manière qui est thread également sans danger.

+0

si vous n'utilisez pas le tableau transmis, utilisez simplement la classe comme paramètre. Fonctionne presque de la même manière, mais n'a pas besoin de créer un nouveau tableau lors de l'accès. E.class fera l'affaire. –

1

Vous avez besoin d'une forme de réification de E dans votre méthode getThings.

Si vous voulez conserver la signature getThings telle quelle, vous pouvez ajouter un paramètre construtor pour fournir la classe réelle E. Avec cette classe, vous pouvez créer un tableau pour passer à la méthode toArray(E[]) de List<E>

private final Class<E> type; 
private final List<E> list; 

public CustomClass(Class<E> type) { 
    this.type = type; 
    this.list = new ArrayList<>(); 
} 

@SuppressWarnings("unchecked") 
public E[] getThings() { 
    Object[] reference = (Object[]) Array.newInstance(type, list.size()); 
    return (E[]) list.toArray(reference); 
} 
+0

désolé j'ai changé la question à un autre exemple parce que je pensais que la réponse pourrait avoir besoin de plus d'informations, mais cela pourrait effectivement fonctionner.Je me demandais juste, comment fonctionne le 'Class type' exactement? – user3785637

+0

Vous pouvez également déplacer le paramètre 'Class type' vers la méthode' getThings() '. – Andreas

+0

est-il possible d'utiliser le type 'Class ' pour assigner un 'Array' à un type? – user3785637