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

Java Discussion :

Peut-on faire une liste de fonctions en Java?


Sujet :

Java

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Points : 159
    Points
    159
    Par défaut Peut-on faire une liste de fonctions en Java?
    Bonjour,

    Par exemple J'ai une classe avec des champs
    A, B, C, D...
    et donc les getters et setters getA(), getB(), getC().

    Y a-t-il un moyen de créer une Map
    {A, getA()}, {B, getB()}...

    Si je boucle sur cette map, je pourrais écrire quelque chose de plus lisible qu'un gros paquet de code répétitif...

    D'après mes souvenirs, ça existait en C, mais je ne trouve rien là-dessus en java.

    Merci.

  2. #2
    Membre confirmé Avatar de Claythest
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    558
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 558
    Points : 554
    Points
    554
    Par défaut
    Non, en Java ce n'est pas possible... Il va te falloir penser autrement

    Ce qui est possible par exemple, c'est tu définis une interface avec une méthode get() par exemple, puis tu définis des objets dont la méthode get() renverra A pour certains, B pour d'autres, ... et tu mets ces objets dans ta liste

  3. #3
    Membre chevronné
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Points : 1 806
    Points
    1 806
    Par défaut
    C'est possible, tu as l'utilisation de ce genre de chose :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Class c = Class.forName(nomDeClasse);
    Method m[] = c.getDeclaredMethods();
    Si tu t'intéresses uniquement aux getters/setters, tu as le package org.apache.commons.beanutils, et notamment BeanUtils.describe qui te renvoie une map de properties.

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Points : 159
    Points
    159
    Par défaut
    Citation Envoyé par Rei Ichido Voir le message
    C'est possible, tu as l'utilisation de ce genre de chose :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Class c = Class.forName(nomDeClasse);
    Method m[] = c.getDeclaredMethods();
    Mmm, dans tous les exemples que je vois, ils utilisent ça pour récupérer des infos sur les méthodes de la classe (paramètres, exceptions, etc); je ne vois personne appeler une fonction.
    Et en plus, je veut une Map avec certaines fonctions (j'aurais bien aimé les rentrer moi-même car en plus de A, B, C..., j'ai toto, titi, etc qui ne m'intéressent pas dans mon traitement).
    Quand à leur exécution, j'ai encore moins trouvé.

    Citation Envoyé par Rei Ichido Voir le message
    Si tu t'intéresses uniquement aux getters/setters, tu as le package org.apache.commons.beanutils, et notamment BeanUtils.describe qui te renvoie une map de properties.
    Là, je crains qu'il y ait à boire et à manger dans cette Map de properties

  5. #5
    Membre chevronné
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Points : 1 806
    Points
    1 806
    Par défaut
    Citation Envoyé par stof Voir le message
    Mmm, dans tous les exemples que je vois, ils utilisent ça pour récupérer des infos sur les méthodes de la classe (paramètres, exceptions, etc); je ne vois personne appeler une fonction.
    Et en plus, je veut une Map avec certaines fonctions (j'aurais bien aimé les rentrer moi-même car en plus de A, B, C..., j'ai toto, titi, etc qui ne m'intéressent pas dans mon traitement).
    Quand à leur exécution, j'ai encore moins trouvé.
    Et pourtant, c'est utilisé fort souvent, c'est la méthode invoke de la classe Method.
    Je te renvoie à la javadoc :
    http://java.sun.com/j2se/1.4.2/docs/...ct/Method.html

    Si tu veux ne garder que quelques méthodes, tu peux toujours définir une liste de noms de méthodes, et ne récupérer que les méthodes dont le nom est dans ta liste.
    Autre possibilité, tu peux générer ta liste de méthodes en allant chercher directement chacune d'elle avec la méthode de la classe Class : getMethod(java.lang.String, java.lang.Class[]).

    Là encore, je te renvoie à la javadoc :
    http://java.sun.com/j2se/1.3/docs/ap...lang/Class.htm

    Là, je crains qu'il y ait à boire et à manger dans cette Map de properties
    Oui il faut avoir un peu l'habitude, mais c'est franchement pratique quand on s'y met.

  6. #6
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 567
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 567
    Points : 21 633
    Points
    21 633
    Par défaut
    Ouais, enfin, personnellement je préfère la recommandation de Claythest.

    Certes, c'est possible de faire ça. Mais il vaut mieux refondre son code pour avoir une approche du traitement plus orientée objet.

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Points : 159
    Points
    159
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Ouais, enfin, personnellement je préfère la recommandation de Claythest.
    Le problème, c'est que j'ai pas compris
    Quels sont les objets dont il parle?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Class MyClass contient :
    Double A;
    Double B;
    ...
    Double Z;
    MyClass implémente une interface qui contient get()... et après?

    PS : pour la solution à base de getDeclaredMethods() et invoke en revanche, c'est bon.

  8. #8
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 567
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 567
    Points : 21 633
    Points
    21 633
    Par défaut
    Fondamentalement ce qu'on te dit, c'est de refondre ton code de sorte de ne pas avoir besoin d'une liste de fonctions, mais d'utiliser un pattern objet adapté à ton besoin.

    Pour te dire comment le faire, il faudrait qu'on comprenne parfaitement ton besoin dans sa globalité... Et puis, c'est ton boulot, hein.

    Maintenant, si tu veux savoir comment faire exactement comme une liste de méthode, mais avec des objets, le plus simple est de définir des functors. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public interface Functor {
      int getValue();
    }
    Et de stocker ces Functors là où tu aurais mis des méthodes. Pour appeler une méthode, tu appelles la méthode unique du Functor. Voilà.

    Bien sûr, c'est à adapter suivant ce que tu essaies effectivement de faire, parce qu'en pratique, j'ai pas compris ce qu'elle fait, ta map.

  9. #9
    Membre confirmé Avatar de Claythest
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    558
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 558
    Points : 554
    Points
    554
    Par défaut
    Comme je l'ai dit et comme l'a souligné thelvin, il te faut penser autrement !

    On ignore tous ce dont tu essaies de faire, donc difficile pour nous de bien te montrer sur ton exemple comment on ferait.

    En gros, le schéma de cette logique est le suivant :

    Tu as une interface (je reprend celle de thelvin, s'il n'y a pas de copyright dessus ) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public interface Functor { 
      public int getValue();
    }
    Ensuite, comme dans ta map tu as des "objets" qui un coup feront getA(), un coup feront getB() ou que sais-je encore, ben tu définis ces objets. Par exemple, tu peux créer plusieurs classes, chacune renvoyant le champ que tu souhaites.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class A implements Functor {
      private int a;
      public int getA() {
        return a;
      }
     
      public int getValue() {
        return getA();
      }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class B implements Functor {
      private int b;
      public int getB() {
        return b;
      }
     
      public int getValue() {
        return getB();
      }
    }

    etc...

    puis tu crées une Map<Maclé, Functor> qui pour chaque élément de Maclé (classe à définir selon tes besoins), associe un object A ou B ou ... et donc en appelant getValue sur cet object, tu récupèreras le champ voulu.


    Une autre solution pourrait être de définir seulement une seule classe de cette sorte :
    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
    public class MaClasse {
      public enum MonEnum{ A, B }
      private int a;
      private int b;
      private MonEnum toGet;
     
      public int getA() {
        return a;
      }
     
      public int getB() {
        return b;
      }
     
      public int getValue() {
        switch(toGet) {
          case A :
            return getA();
          case B :
            return getB();
        }
      }
    }
    Et donc ensuite, il suffit de créer la Map<MaClasse.MonEnum, MaClasse>, et de la remplir avec des objets dont la valeur toGet est renseignée de manière à avoir le comportement souhaité...

    Maintenant, là on est dans de la bidouille, et je suis quasi sûr que connaissant ton problème, on peut s'en sortir avec quelque chose de beaucoup plus simple...

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Points : 159
    Points
    159
    Par défaut
    Citation Envoyé par Claythest Voir le message
    Une autre solution pourrait être de définir seulement une seule classe de cette sorte :
    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
    public class MaClasse {
      public enum MonEnum{ A, B }
      private int a;
      private int b;
      private MonEnum toGet;
     
      public int getA() {
        return a;
      }
     
      public int getB() {
        return b;
      }
     
      public int getValue() {
        switch(toGet) {
          case A :
            return getA();
          case B :
            return getB();
        }
      }
    }
    Et donc ensuite, il suffit de créer la Map<MaClasse.MonEnum, MaClasse>, et de la remplir avec des objets dont la valeur toGet est renseignée de manière à avoir le comportement souhaité...
    Oui, c'est pas mal non plus ça

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Points : 159
    Points
    159
    Par défaut
    Mais faut un argument à la fonction getValue (on ne peut rien faire si toGet est privé de l'extérieur).
    Et on ne peut pas parcourir les enum apparemment du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for(int i=0; i<MyClass.MonEnum.values().length; i++){
    double test = mJ.getValue(MyClass.MonEnum[i]);
    }
    je vais plutôt faire un tableau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public String[] listChamps = { "A", "B", "C" };
     
    et public double getValue(String champ) {
    ...
    }

  12. #12
    Membre confirmé Avatar de Claythest
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    558
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 558
    Points : 554
    Points
    554
    Par défaut
    Citation Envoyé par stof Voir le message
    Mais faut un argument à la fonction getValue (on ne peut rien faire si toGet est privé de l'extérieur).
    Je ne l'avais pas mis, je pensais que c'était évident, mais t'as raison cela ne l'était pas : je pensais rajouter un setter du l'attribut toGet (le nom me plait bof bof d'ailleurs ^^). monobjet.setToGet(MaClasse.MonEnumeration.A();

  13. #13
    Membre chevronné
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Points : 1 806
    Points
    1 806
    Par défaut
    Citation Envoyé par stof Voir le message
    Mais faut un argument à la fonction getValue (on ne peut rien faire si toGet est privé de l'extérieur).
    Et on ne peut pas parcourir les enum apparemment du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for(int i=0; i<MyClass.MonEnum.values().length; i++){
    double test = mJ.getValue(MyClass.MonEnum[i]);
    }
    Je te conseille fortement si tu veux faire ce genre de choses de passer par une enum.
    Et on peut faire une itération :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    for(MonEnum e : MonEnum.values()){
       Objet test = mJ.getValue(e);
    }
    J'ai changé le type de retour en Objet, si tu veux pouvoir accéder à n'importe quelle propriété de ton objet par ce genre d'astuce, autant rester générique. Ou alors tu définis une interface (et donc une enum) par type de retour, s'ils sont en nombre restreint.

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

Discussions similaires

  1. Réponses: 9
    Dernier message: 21/10/2014, 19h08
  2. Réponses: 9
    Dernier message: 25/01/2012, 18h07
  3. [MySQL] Faire varier une liste en fonction d'une autre dans un formulaire
    Par lemirandais dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 19/01/2009, 23h45
  4. [TableAdapter] Peut-on en faire une liste générique ?
    Par sybaris dans le forum Framework .NET
    Réponses: 4
    Dernier message: 02/10/2008, 16h31
  5. Réponses: 14
    Dernier message: 09/04/2008, 15h45

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