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

  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.

  8. #8
    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
    Bon ! Je me répond à chaque mais je viens de rendre compte quelque chose, je ne suis pas sur que ma classe TableauGenerique soit si générique que ça ???

    j'ai un import de la classe reflect.array ce qui veut dire que Array.newinstance n'est pas générique, je ne suis pas hors sujet pour la générécité ? Je pense que c'est plus adapté pour l'autre classe 'Tableau" qui elle doit utiliser Array.reflect mais sans générécité ?

    Aie! Aie ! Aie ! J'ai mal à la tête.

    [EDIT]Dans l'énoncé de mon exo il est noté ceci :
    Completez enfin la classe TableauGenerique, solution generique (sans
    introspection) au probleme pose.[/EDIT]

  9. #9
    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
    Hum, tu veux dire que tu dois écrire une version intermédiare utilisant Array.newInstance, mais non générique, donc toujours avec Object[] en paramètre. Là, tu devrais voir immédiatement comment l'écrire : comme tu connais le type des éléments du tableau (c'est Object), il te suffit de le passé en argument de newInstance(). Mais attention, lorsqu'on déclare une variable, la syntaxe Java fait qu'on donne le nom de la classe directement. Mais un argument de méthode doit être une instance de classe.

    Comment récupérer l'instance de classe qui correspond à la classe d'un objet ?

    • Lorsqu'on a une variable, on peut appeler la méthode getClass() qui retourne l'instance de la classe de la variable. On pourrait par exemple écrire init.getClass() pour récupérer l'instance de classe de la variable init.
    • Lorsqu'on connait le nom de la classe, on peut directement utiliser son attribut class. Comme dans ton cas, on connait la classe, on peut écrire : Object.class.
      Donc, l'appel de newInstance devient :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      Object[] object = (Object[]) Array.newInstance( Object.class, taille );
    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.

  10. #10
    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
    Ok ! Je pense que le plus simple c'est que je te post le sujet car je me rend compte que j'oublie des morceaux à chaque fois donc voici ce qui est dit :

    On s'interdit d'utiliser la genericite et on desire ecrire une methode statique generale (a defaut d'etre
    generique) pour pouvoir agrandir un tableau. Par exemple, si T est un tableau d'entiers de taille 5, on
    veut que Tableau.agrandir(T,10,100) retourne un tableau de taille 10 dont les 5 premieres cases
    contiennent les 5 premiers elements de T et dont toutes les autres cases contiennent 100. Le nouveau
    tableau doit avoir des elements du meme type que le tableau intial (et non pas le type Object). Ainsi,
    si on execute la methode main de la classe suivante :

    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 class Tableau {
    public static Object[] agrandir(Object[] tab, int taille, Object init) {
    ...
    }
    public static void main(String[] args) {
    Integer[] t1 = { 0,1,2,3,4 };
    String[] t2 = { "aa", "bb", "cc" };
    Integer[] tt1 = (Integer[]) Tableau.agrandir(t1, 10, 100);
    String[] tt2 = (String[]) Tableau.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();
    }
    }
    on veut obtenir le resultat suivant :
    0 1 2 3 4 100 100 100 100 100 100
    aa bb cc vide vide
    1
    Verifiez que l'implementation triviale de agrandir (dans la classe TableauFaux fournie) ne marche
    pas. Ecrivez la bonne version de agrandir dans la classe Tableau en utilisant, entre autre, la classe
    java.lang.reflect.Array. Completez enfin la classe TableauGenerique, solution generique (sans
    introspection) au probleme pose.
    En revanche pour l'autre classe qui n'est pas générique je peux utiliser ce que je viens de faire pour celle qui est générique ? S'il faut supprimer la classe object, faut-il que je me serve du sous-typage (ex : <? super Number>) si c'est ça ? Il faut que je sache quelle classe est la super classe des types ?

  11. #11
    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
    OK. Non, ne te lance pas dans des <? extends Number>, c'est du spécifique à une notion de quelque chose qui étend du Number, ce qui n'est pas le cas par exemple de String. Tu ne peux pas envisager de faire des traitements spécifiques pour tous les cas, d'autant plus que leur nombre est à priori infini.

    Ce qu'on demande c'est de faire une méthode qui retourne du Object[] mais que tu pourras caster en ce que tu sais qu'il faut caster, c'est-à-dire le type des éléments du tableau en paramètre. Ce qui est matérialisé par les appels de la méthode dans le code donné :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Integer[] tt1 = (Integer[]) Tableau.agrandir(t1, 10, 100);
    String[] tt2 = (String[]) Tableau.agrandir(t2, 5, "vide");

    Donc la signature tu la méthode que tu as a écrire doit rester ce qu'elle est : public static Object[] agrandir(Object[] tab, int taille, Object init) {.

    Mais dans la méthode le tableau tab2 doit être instancié dans le bon type, pour pouvoir être casté dans le type voulu.
    Si tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Object[] array = new Integer[10];
    Integer[] arrayint = (Integer[])array;
    Pas de problème, arrayint peut être casté en Integer[], parce que c'est bien la classe de l'instance, même si le type de la variable est Object[], donc plus générique

    Mais si tu écrivais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Object[] array = new Object[]{ new Integer(1), new Integer(2) };
    Integer[] arrayint = (Integer[])array;
    ça planterait à l'exécution (ClassCastException). Parce que la classe de l'instance est un Object[], même s'il contient bien des Integer. C'est un Object[] donc ne peut être casté en Integer[].

    Donc en résumé, tu dois instancier ton tableau dans le bon type, celui des éléments du tableau tab passé en paramètre. Si tu as bien lu mes précédents messages, tu devrais trouver la solution...
    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.

  12. #12
    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
    Ok ! Merci pour l'info alors j'ai fait cela

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    	public static Object[] agrandir(Object[] tab, int taille, Object init) {
     
    		Object[] tab2 = (Object[]) 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] = init;
     
    		return tab2;
    	}
    Si j'ai bien respecté tes explications et écouté attentivement ce que tu m'as dit, normalement ce que j'ai écrit est juste, est ce bien cela ?

  13. #13
    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
    Oui, si j'ai bien compris la demande, à part que je ne vois pas ce que vient faire le + 1 dans la borne de départ de la seconde boucle, mais comme il semble être dans ton code de départ donné par le prof, il doit y avoir une volonté obscure de ne pas mettre de valeur dans l'élément d'indice tab.length...
    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.

  14. #14
    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
    Super ! Bon j'aurai au moins compris quelque chose, concernant le lenght, je ne dois pas y toucher c'est effectivement le programme de l'enseignant donc "Don't Tocuh !!!"

    Est ce que ça t'embête si on revient sur mon dernier exo qui était la générécité ?

    Je suis pas sur que ce que j'ai fait soit bien générique, je remet mon code au besoin.

    Merci 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
     
    import java.lang.reflect.Array;
     
    	public static <T> T[] agrandir(T[] tab, int taille, T init) {
     
    		/** La déclaration du tableau */		
    		@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;
    	}

  15. #15
    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
    Je vois mal comment on pourrait faire plus générique : on ne mentionne plus explicitement le type des éléments du tableau nulle part, puisqu'il est toujours référencé soit par un type paramétré (T), soit par getClass().getComponentType(), mais comme on ne peut pas instancier un tableau de type non explicite autrement, il n'y a que ce moyen là (on ne peut pas écrire new T[...]). Après on peut blinder le code contre les erreurs possibles (par exemple si le tab est null, aller chercher la class de init ; si il est aussi null, on ne peut rien faire, sauf ajouter un paramètre de type Class<T>), mais , mais je pense qu'on déborde du cadre de l'exercice.

    Il y a juste le dernier cast qui n'est pas indispensable (dans return (T[]) tab2;), parce que tab2 c'est déjà du T[].
    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.

  16. #16
    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
    Très bien ! Merci pour ton aide, pour le temps que tu as passé à m'aider et tes explications qui m'ont été très précieuse.
    Je vais rester là dessus car je pense que mon sujet est clos car tout fonctionne et resemble à ce qui est demandé.

    Je sais pas si ça sera suffisant mais un grand MERCI, j'espère qu'un jour je pourrais te rendre la pareille.

    Je vais créer un nouveau post qui concerne la récursivité, vu qu'il ne fait plus partie de ce sujet, je ne vais donc pas l'expliquer ici.

    Merci, Merci et 10000 mercis pour ton aide

+ 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