IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Collection et Stream Java Discussion :

Comment écrire une méthode qui retourne un ArrayList


Sujet :

Collection et Stream Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 256
    Par défaut Comment écrire une méthode qui retourne un ArrayList
    Bonsoir à tous !

    Je sais pas comment vous le dire mais le titre en dit déjà long. Je suis depuis le début du WE sur ce maudit bout de programme et j'ai beau chercher dans tous les sens je n'y arrive pas !!!!

    Alors voici mon problème :
    Je dois retourner une collection de type ArrayList mais ce maudit compilateur me jette, vous trouverez ci-dessous mon code en espérant que vous allez pouvoir m'aider.

    En attendant je vous remercie à tous pour votre aide.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    	public static <T> T agrandir(T[] tab, int taille, T init) {
    		ArrayList<?>[] tab2 = new ArrayList<?>[taille];
    		for ( int i = 0; i < tab.length; i++ )
    			tab2[i] = (ArrayList<?>) tab[i];
    		for ( int i = tab.length + 1; i < taille; i++ )
    			tab2[i] = (ArrayList<?>) init;
    		return <T extends ArrayList<?>> tab2;
    	}

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    Pour écrire une méthode qui retourne un type donné, il n'y a pas à tortiller :

    Code pseudojava : Sélectionner tout - Visualiser dans une fenêtre à part
    type nomDeMethode(...)

    Donc, pour retourner un ArrayList, tu devrais avoir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public static ArrayList methodeTruc() {...}
    Si tu as besoin de paramétrer cet ArrayList, il faut déclarer son paramètre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public static <T> ArrayList<T> methodeTruc() {...}
    Le premier <T> sert à déclarer le type paramétré : ici, on l'appelle T et ça peut être n'importe quoi. Le <T> à la fin de ArrayList est l'utilisation de ce type : ici, il est utilisé pour dire que l'ArrayList va être parémétré avec ce type T.

    Dans le cas suivant, on déclare T comme étendant la classe Truc.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public static <T extends Truc> ArrayList<T> methodTruc() {...}
    A partir du moment où on a une instance d'un type donnée à retourner, on doit au moins retrouver ce type dans le machin qui est retourné :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public static <T extends Truc> ArrayList<T> methodTruc() {
     
        ArrayList<T> resultat = new ArrayList<>(); 
     
     
        return resultat;
     
    }
    Dans ton code,

    • ta méthode retourne une instance de T
    • tu déclares tab2 comme tableau d'ArrayList de de quelque chose que tu ne saurais pas ce que c'est (le <?>)
    • tu retournes ce tab2 qui n'est donc pas du T, mais du ArrayList<?>[] et comme ça ne compîle pas (évidemment, ce ne sont pas les mêmes types), tu écris un truc (<T extends ArrayList<?>>) qui n'a rien à faire là (peut-être ton intention était-elle de caster, mais pour le coup, même avec la bonne syntaxe ((T)tab2), ça ne peut pas fonctionner (le cast c'est pas une conversion ou une transformation, c'est une adaptation du type, qui ne change pas la classe de l'instance castée, et certainement pas converti de n'importe quoi en autre chose).
    • Sinon, tu passes en paramètre du T[], donc un tableau de T, pas un tableau de ArrayList<?>. Donc caster en ArrayList<?> ne vas pas fonctionner dans tous les cas d'appel (si le tableau ne contient pas des ArrayList, tu auras une ClassCastException). Pareil pour le cast de init...
    • Je me doute un peu de ce que tu cherches à faire : la seconde boucle commence en tab.length+1, alors que je pense qu'elle devrait commencer en tab.length...



    Ensuite, dis-nous plutôt ce que tu cherches à faire au juste. Précises les types réels des paramètres, en entrée, comme en sortie, et que le but de la méthode. Et on pourra te guider.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 256
    Par défaut
    Bonjour joel.drigo et désolé de te répondre tardivement mais j'ai voulu avancer dans mes exos donc je n'ai pas vu ta réponse !

    Merci pour tes réponses, je n'ai pas tout compris mais ce n'est pas de ta faute. Je débute en tout (programmation et JAVA), c'est un exercice que m'a remis mon enseignant et que je dois remmetre au plus tard ce vendredi.
    Le but de cet exercice est de convertir le programme existant en type générique en utilisant entre autre la classe "java.lang.reflect.Array" mais ça je crois que je ne l'ai pas fait.

    Je trouve que JAVA est très compliqué et est certainement réservé à un certain type de communauté et je ne pense pas en faire partie car entre :
    - Généricité,
    - Interface,
    - Récursivité (en plus je suis nul en math),

    J'ai dû mal à faire la part des choses, pire encore ! Je passe limite des nuits là dessus ! Le matin on me demande si je me drogue .... Pas cool !!!

    Si tu as un peu de temps à me consacrer, je voudrais bien de ton aide car là ! Je suis un petit poisson au milieu de l'océan ?

    Ci-dessous le code du programme existant à transformer en générécité avec la classe "java.lang.reflect.Array"

    Je t'en remercie d'avance.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    public class TableauFaux {
     
    	/**
             * Fabrique et retourne un tableau de taille 'taille' contenant
             * les mêmes objets que ceux contenus dans 'tab' suivi de
             * la valeur 'init'
             * Précondition : taille >= tab.length
             */
    	public static Object[] agrandir(Object[] tab, int taille, Object init) {
    		Object[] tab2 = new Object[taille];
    		for ( int i = 0; i < tab.length; i++ )
    			tab2[i] = tab[i];
    		for ( int i = tab.length + 1; i < taille; i++ )
    			tab2[i] = init;
    		return tab2;
    	}
     
    	/**
             * Le programme principal
             */
    	public static void main(String[] args) {
     
    		Integer[] t1 = { 0,1,2,3,4 };
     
    		String[] t2 = { "aa", "bb", "cc" };
     
    		Integer[] tt1 = (Integer[] ) TableauFaux.agrandir(t1, 10,100);
     
    		String[] tt2 = (String[]) TableauFaux.agrandir(t2,5,"vide");
     
    		for ( Integer i : tt1 )
    			System.out.print(i + " ");
     
    		System.out.println();
     
    		for ( String s : tt2 )
    			System.out.print(s + " ");
     
    		System.out.println();
    	}
    }

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Donc il est nullement question d'ArrayList. La méthode que tu dois utiliser est Array.newInstance(type, taille). Le paramètre type est le type des éléments dans le tableau. Tu peux obtenir ce type à partir du tableau passé en argument (sauf si celui-ci est null, puisque tu obtiendras une NullPointerException dans ce cas) par tab.getClass().getComponentType(). La méthode newInstance retourne de l'Object : pour obtenir un T[] (le tableau "générique"), il faudra donc caster en (T[]).

    En ce qui concerne la signature de la méthode, il suffit d'écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public static <T> T[] agrandir(T[] tab, int taille, T init) {
    Le premier <T> définit donc le type générique qu'on va utiliser (voir mon explication plus détaillée dans le message précédent) : ici on l'appelle juste T (c'est un nom, on peut mettre ce qu'on veut, tant que ce n'est pas un mot clef Java, ou çà ne rentre pas en conflit avec autre chose, mais on utilise souvent T, comme le T de Type) pour pouvoir y faire référence la où on en a besoin, et il indique qu'on veut pourvoir appeler cette méthode sur n'importe quel type de tableau. Ensuite, il suffit de remplacer Object dans la signature de la méthode à transformer par T. Puis dans la méthode, le Object[] tab2 = new Object[taille]; par l'appel de Array.newInstance...

    PS : Java n'est pas beaucoup plus compliqué qu'autre chose : il y a probablement des langages plus simples au premier abord, parce que plus limités en syntaxe, et encore, ce n'est toujours le cas. Mais il est normal, quand on débute, d'avoir des difficultés, comme avec tout : je ne peux que te conseiller de lire plusieurs fois ton cours, de consulter des tutoriels (comme ceux de la rubrique de Developpez), de pratiquer (de faire des exercices), et ça devrait rentrer petit à petit. Bon, probablement que d'être nul en math ne t'aide pas sur certains aspects, mais d'un autre côté, être super bon en math ne t'aidera pas forcément non plus (je me souviens des TD de pascal en DEUG MP : beaucoup de très forts en math galéraient pas mal pour écrire des programmes, même pour des algorihmes d'applications mathématiques, comme un produit de matrices par exemple).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 256
    Par défaut
    Merci pour ton aide c'est très gentil et les conseils sont très important dans un apprentissage. J'ai déjà visualiser certains cours sur le site, ils sont bien expliqués mais là ou je but c'est dans la mise en oeuvre.
    J'ai bien compris le but de la générécité mais ce que je n'arrive pas à faire, c'est avoir l'idée de mettre ça à la place de ça (bon ! mon explication est arcaïque mais elle se résume à "ça").

    Quand je lis tes réponses, je m'aperçois que pour toi c'est comme faire du vélo, juste à monter sur la selle, pédaler et hop ! C'est partit ! Pour moi en revanche, je me demande à quoi sert le vélo ????

    Pour finir, ta petite phrase de fin de ton précédent post est plutôt sympa et rassurante ;-) après on est Einstein ou pas .... .

    Juste pour revenir à mon exo, je viens de me rendre compte que j'ai tout mélangé, en fait il y a 2 classes à faire :
    - 1 nommée "TableauGenerique" qui elle transforme la méthode en exploitant uniquement la générécité (pas de reflect.array).
    - 1 nommée "Tableau" qui elle transforme la méthode avec l'utilisation de la classe reflect.array sans générécité.

    Le tout en se basant sur la classe "TableauFaux" que j'ai indiqué dans mon précédent post.

    Alors, j'ai essayé de reproduire ce que tu m'as dit de faire mais vu que j'ai mélangé les 2, j'ai fait un peu du n'importe quoi, ci-dessous mon picasso !
    Il y a pleins d'erreurs mais c'est normal car "Array.newInstance" je ne sais pas où il faut que je la déclare exactement ? Dans la déclaration de la méthode ... non, puisque que j'ai reproduit ta déclaration et elle n'est pas indiquée dedans, donc je pense que c'est dans le corps de la méthode mais j'ai une erreur d'autant plus que tab2 à disparu.

    Merci de prendre du temps pour moi, j'espère en faire de même dans l'avenir pour des gens qui galèrent comme moi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    	public static <T> T[] agrandir(T[] tab, int taille, T init) {
     
    		/** La collection ArrayList */		
    		T[] tab2 = (T[]) Array.newInstance(tab.getClass(), taille);
     
    		for ( int i = 0; i < tab.length; i++ )
    			tab2[i] = tab[i];
     
    		for ( int i = tab.length + 1; i < taille; i++ )
    			tab2[i] = (T) init;
     
    		return (T[]) tab2;
    	}

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 256
    Par défaut
    Désolé ! Je viens de me rendre compte de mon erreur que tu m'avais sagement indiqué dans ton post, j'ai omis de mettre "getComponentType()" et après ajout, ça fonctionne nickel !!!!
    Maintenant, je passe à l'autre classe "Tableau" avec l'utilisation de laclasse "reflect.array" mais là je sais pas s'il faut que je change la classe Object dans la déclaration de la méthode ???

    Ci-joint la méthode générique modifier et qui fonctionne grâce à toi !!!! Un grand MERCI
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    	public static <T> T[] agrandir(T[] tab, int taille, T init) {
     
    		/** La collection ArrayList */		
    		@SuppressWarnings("unchecked")
    		T[] tab2 = (T[]) Array.newInstance(tab.getClass().getComponentType(), taille);
     
    		for ( int i = 0; i < tab.length; i++ )
    			tab2[i] = tab[i];
     
    		for ( int i = tab.length + 1; i < taille; i++ )
    			tab2[i] = (T) init;
     
    		return (T[]) tab2;
    	}

  7. #7
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Reprenons Array.newInstance(tab, taille);Cette méthode créé une instance de tableau (l'équivalent d'un new machin[...]). Le premier paramètre, c'est le type, donc une classe, des éléments : là, toi tu passes un tableau, par une classe. Pour obtenir cette classe, que tu ne peux pas connaitre, puisqu'on fait du générique, il faut aller la chercher quelquepart. On pourrait la passer en paramètre de la méthode, mais là on passe en paramètre un tableau dont les éléments sont de la classe qu'on veut justement, donc on peux récupérer cette classe par ce tableau, comme je l'ai dit dans mon dernier message.

    Le second paramètre est correct : c'est bien la variable taille qui contient la taille du tableau qu'on veut obtenir.

    Ensuite, cette méthode créé juste une instance de tableau : toi, tu as besoin d'utiliser cette instance de tableau. Il te faut donc mettre cette instance dans une variable pour la manipuler, la variable tab2 justement. Et comment met-on une instance dans une variable ? Avec =. Mais comme je te le disais newInstance() retourne une instance de tableau mais typée Object (voir la javadoc de cette méthode). Or, la variable tab2 doit un être un T[]. Il faut donc caster.

    Donc, en résumé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public static <T> T[] agrandir(T[] tab, int taille, T init) { // on passe un tableau de T, on veut obtenit en retour un tableau de T
     
       T[] tab2 = (T[]) Array.newInstance( tab.getClass().getComponentType(), taille ); // on créé tab2, un tableau de T, en récupérant la classe sur le tableau tab, passé en paramètre
     
       // on remplit le début avec le contenu du tableau tab, en copiant un à un les éléments
       for ( int i = 0; i < tab.length ; i++ ) {
          tab2[i] = tab[i]; 
       }
     
       // on remplit la suite jusqu'à la fin avec ce qui est passé en paramètre init
       for ( int i = tab.length; i < taille; i++ ) {
          tab2[i] = init;
       }
     
       return tab2; // on retourne tab2
     
    }
    Par contre, je ne vois pas comment on pourrait faire sans java.lang.reflect.Array (on ne peut pas écrie new T[taille]).

    EDIT: oups, je n'avais pas vu que tu avais reposté entre temps.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. une méthode qui retourne une valeur
    Par soujava dans le forum Débuter avec Java
    Réponses: 8
    Dernier message: 17/04/2008, 14h29
  2. [JUnit] Comment tester une fonction qui retourne un booléen
    Par Raiden1234 dans le forum Tests et Performance
    Réponses: 2
    Dernier message: 15/12/2007, 19h29
  3. Réponses: 10
    Dernier message: 13/08/2007, 16h12
  4. Réponses: 10
    Dernier message: 28/07/2007, 15h53
  5. Comment créer une fonction qui retourne un tableau?
    Par Dereck07 dans le forum Delphi
    Réponses: 4
    Dernier message: 26/04/2007, 13h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo