Forum Programmation.java Siouxerie en java

Posté par  (site web personnel) .
Étiquettes : aucune
0
10
mai
2007
Le gros problème de java, c'est l'impossibilité (parait-il bientôt corrigée) de mettre des fonction annonymes (ou pas) en argument de fonction.

Comme j'en avais marre des limitations de Vector, j'ai fait ma classe avec entre autre une méthode

public synchronized Vecteur restrict_elt_with_func(E other, String obj, String func)

Le but de cette méthode est de restreindre les éléments du vecteur à un élément sur lequel une fonction donnée s'applique.
Un exemple vaut mieux qu'un long discours, j'aimerai faire :


monvecteur.restrict_elt_with_func("toto", "String", "startsWith")

de sorte que ça me crache toutes les chaînes du Vecteur commençant par "toto"


donc dans le code suivant
public synchronized Vecteur restrict_elt_with_func(E other, String obj, String func) {
  Vecteur res = new Vecteur();
  if (elementData != null)
   for (int i=0 ; i<elementData.length ; i++) {
   E self_elt;
   self_elt = (E)elementData[i];
   if (self_elt.equals(other))
    res.add(self_elt);
  }
  return res;
}


Faut que je remplace le equals, par une invoquation de la méthode donnée en argument.
J'ai bien ce code là


private Object lancerMethode(Object obj, Object[] args, String nomMethode) throws Exception
{
  Class[] paramTypes = null;
  if(args != null)
  {
   paramTypes = new Class[args.length];
   for(int i=0;i<args.length;++i)
    {
    paramTypes[i] = args[i].getClass();
    }
   }
  Method m = obj.getClass().getMethod(nomMethode,paramTypes);
  return m.invoke(obj,args);
}


Le problème, c'est que je sais pas comment invoquer le receveur, dans mon cas, ie lui faire exécuter dans mon exemple :

self_elt.startsWith(other)

Une idée ?
  • # Je ne suis pas sur de bien comprendre le problème...

    Posté par  . Évalué à 2.

    C'est lancerMethode(self_elt, new Object[] {other}, func) que tu veux faire ?
  • # Motif de conception « Command »

    Posté par  . Évalué à 6.

    Tu fais comme pour Runnable et cie : tu encapsules ta fonction dans un objet. (Donc tu ne passes pas de String. Ce n’est pas propre. Java n’est pas interprété.) Donc, ici :
    interface FonctionBoolStringString {
        boolean applique(String arg);
    }
    
    Vecteur restrict_elt_with_func(FonctionBoolString func) {
        Vecteur res = new Vecteur();
        if (elementData != null)
            for (int i=0 ; i<elementData.length ; i++) {
                E self_elt;
                self_elt = (E)elementData[i];
                if (func.applique(self_elt))
                    res.add(self_elt);
            }
        return res;
    }
    
    Et tu appelles avec :
    restrict_elt_with_func(new FonctionBoolString() {
        boolean applique(String arg) {
            return arg.startsWith("other");
        }
    });
    
    Bon, là j’ai fait l’appel avec un objet anonyme directement issu de l’interface mais tu peux faire des objets nommés issus de classes nommées qui implémentent l’interface FonctionBoolString.
    
    Dans le royaume des noms, les verbes sont forcément accompagnés.
    
    • [^] # Re: Motif de conception « Command »

      Posté par  . Évalué à 3.

      Je pense que la bibliothèque functor de jakarta peut s'avérer utile pour ce genre de choses :
      http://jakarta.apache.org/commons/sandbox/functor/
    • [^] # Re: Motif de conception « Command »

      Posté par  (site web personnel) . Évalué à 2.

      (Donc tu ne passes pas de String. Ce n’est pas propre. Java n’est pas interprété.)
      Ouais, Javouille, les inconvéniants d'un langage compilé sans les avantages...

      Plus constructivement, et pour l'intelligence collective, il faut écrire l'objet comme suit :

      interface FonctionBool {
        public abstract boolean compare(Object el1, Object el2);
        public abstract boolean do_something(Object el);
      }

      sinon le compilateur nous jette.

      Le do_something permet par exemple de faire des map/fold/filter

      Exemple le map :

      Vecteur map(FonctionBool func) {
        Vecteur res = new Vecteur();
        if (elementData != null)
         for (int i=0 ; i<elementData.length ; i++) {
          E self_elt;
          self_elt = (E)elementData[i];
          func.do_something(self_elt);
         }
        return res;
      }

      maliste.map ( new FonctionBoolString() {
        boolean do_something(String arg) {
         System.out.println(arg);
      }
      });


      Mais c'est surtout pour les fold(gauche|droite) et le filter que c'est intéressant.

      En tout cas merci, ça m'a débloqué :)

      « Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker

      • [^] # Re: Motif de conception « Command »

        Posté par  . Évalué à 3.


        interface FonctionBool {
        public abstract boolean compare(Object el1, Object el2);
        public abstract boolean do_something(Object el);
        }


        Je pense que le "abstract" est inutile dans une interface.
      • [^] # Re: Motif de conception « Command »

        Posté par  . Évalué à 2.

        Ça devrait fonctionner avec des « E » (puisque c’est le type de self_elt).

        Ce serait peut-être une idée de typer un peu mieux (passer par des templates p.ex. : le transtypage de elementData[i] en est une indication).

        Oui, être obligé de spécifier tous les types (alors qu’ils pourraient être déduits) est une plaie de Java, mais si c’est pour passer des Objects dans tous les coins, autant choisir un autre langage : Java n’a plus d’intérêt si on n’utilise pas son typage fort.

        Je t’encourage à lire Design Patterns ( http://en.wikipedia.org/wiki/Design_Patterns pour l’isbn). La grande majorité des motifs de conception objet servent à faire de la programmation fonctionnelle en programmation objet.
  • # java.lang.reflect

    Posté par  . Évalué à 1.

    Ce que tu veux se trouve dans le package jav.lang.reflect, tu y a une classe Method que tu pourra ensuite utiliser pour exécuter la méthode qu'elle représente sur des instance de la classe à laquelle appartient la méthode.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.