Lambda expression en Java 8

Lambda calculus is a formal system for functio...

Lambda calculus is a formal system for function definition, function application and recursion introduced by Alonzo Church in the 1930s. (Photo credit: Wikipedia)

Java 8 qui est sur le point de sortir nous promet encore plus de programmation fonctionnelle.

Le parcours  du  tutoriel en ligne justifie cela par l’efficacité de l’approche. Les lambdas expressions permettent en effet de décrire des fonctions anonymes, sans nom et raccrochées à aucun objet. Sans les lambda expression le langage oblige alors à créer une classe (anonyme si nécessaire) et une méthode.  Inutile et superflu parait-il…

Supposons  que l’on veuille pouvoir passer un comportement à une méthode. Comme on n’avait pas de pointeur sur fonction en Java jusque là, on devait définir une interface puis l’implémenter et passer une instance implémentante à la méthode.

Une interface:

public interface Calculator {
        int function(int x);  
}

Une implémentation:

public class InterfaceImplementor implements Calculator {
    Override
    public int function(int x) {
        return 222;
    }
}

définition de la méthode paramétrable par une interface fonctionnelle:

 int calcul(Calculator c){
        return c.function(0); 
  }

L’appel se fait alors par un code (encore du code) du genre:

calcul(new InterfaceImplementor());

On peut éviter de définir une classe en créant une instance d’une classe anonyme:

calcul(new Calculator(){

            @Override
            public int function(int x) {
               return 999;
            }

Le JDK 8 arrive pour éviter encore plus de code en proposant de définir une lambda expression c’est-à-dire une méthode anonyme sans classe. Pour pouvoir tester cette future nouvelle fonctionnalité il faut télécharger le JDK 8 (non finalisé) et Netbean 7.4 (non finalisé) pour pouvoir écrire:

calcul((x) -> 555);

Il y a là une petite complexité (pardon nouveauté) sous le clavier. Le compilateur autorise ici 2 raccourcis: pas d’interface, pas de méthode.  La simple définition d’une fonction qui répond au typage de la méthode de l’interface Calculator suffit pour que le compilateur câble tout correctement. On peut se dire que c’est une bonne chose mais là où ça se complique c’est que Java 8 offre la possibilité d’utiliser une méthode existante sans passer par la case refactoring pour faire rentrer la méthode existante dans le moule d’une interface. Ainsi on peut utiliser n’importe quelle méthode ayant la bonne signature fonctionnelle: dans notre exemple int -> int. L’appel ressemble alors à cela:

calcul(ecxistingObject::existingMethod);

Voici le code complet permettant de voir l’ensemble des évolutions du langage abordées dans ce billet:

Une interface pour la manière de faire « old school »:

package lambda;

public interface Calculator {
        int function(int x);    
}

et son implémentation:

package lambda;

public class InterfaceImplementor implements Calculator{
    @Override
    public int function(int x) {   
       return 222;
    }
}

Une classe existante dont on peut réutiliser une méthode sans avoir à implémenter l’interface vue plus haut:

package lambda;

public class ExistingClass {
 private int i = 777;

 public int uneFonction(int x) {
   return i;
 }
}

Et les différentes manières de passer une fonction à une méthode:

package lambda;

public class Lambda {
 /**
  * @param args the command line arguments
  */
 public static void main(String[] args) {
   // TODO code application logic here

   Lambda l = new Lambda();
   int i = 0;

   // old school, plain class creation

   i = l.calcul(new InterfaceImplementor());
   System.out.println(i);

   // old school, anomymous class

   i = l.calcul(new Calculator(){
           @Override
       public int function(int x) {
         return 999;
       }
     });
   System.out.println(i);

   // anonymous method, lambda expression

   i  = l.calcul((x) -> 555);
   System.out.println(i);

   // method reference !

   ExistingClass existingObject = new ExistingClass();
   i = l.calcul(existingObject::uneFonction);
   System.out.println(i);
 }

 int calcul(Calculator c){
   return c.function(0);
 }
}

Dont l’exécution donne:

run:
 222
 999
 555
 777
 BUILD SUCCESSFUL (total time: 1 second)
Publicités
Publié dans Langage | Tagué | Laisser un commentaire

Code d’initialisation en Java

Coding

Coding (Photo credit: Omer van Kloeten)

La lecture du tutoriel Java mérite que l’on s’y attarde, que ce soit pour le débutant ou bien pour celui qui vise l’excellence. Certains aspects du langage fort intéressants y sont bien expliqués, comme le code d’initialisation. On le trouve il est vrai rarement dans le code d’application métier mais plutôt dans le code de framework ou d’application standalone qui doivent initialiser de la « plomberie » comme une connexion de base de donnée ou l’activation d’un service de nommage. Mais il parait qu’il n’y a rien de tel que la lecture du code d’un bon framework pour apprendre à faire du bon code alors attardons nous sur les mécanisme offert pas le langage en matière d’initialisation.

Dans le tutoriel on distingue 3 types de code d’initialisation:

  • le code d’initialisation static
  • le code d’initialisation d’instance
  • le code d’initialisation de variable

L’initialisation statique pourra être utilisée pour s’occuper de choses globales à l’application et l’initialisation d’instance pour des aspect liée à l’instance comme par exemple pour faire un suivi des instances en utilisant une référence faible (weak reference). Le tutoriel présente une exemple de code d’initialisation de variable par une méthode final arguant que le contraire peu poser des problèmes. Peut-être… Un petit bout de code permet de voir comment tout cela s’articule.

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package initinstancemenber;

/**
 *
 * @author thierry
 */
public class InitInstanceMenber {

    private int i = initMyIMember();

    {
        System.out.println("instance init code");
    }

    static {
        System.out.println("class init code");
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        InitInstanceMenber a = new InitInstanceMenber();
        System.out.println("i=" + a.i);
        a= new InitInstanceMenber(){
            @Override
            protected int initMyIMember(){
                System.out.println("overriden init member");
                return 1;
            }
        };
        System.out.println("i=" + a.i);
    }

    protected int initMyIMember(){
        System.out.println("init member");
        return 0;
    } 
}

Dont voici l’exécution:

run:
class init code
init member
instance init code
i=0
overriden init member
instance init code
i=1
BUILD SUCCESSFUL (total time: 0 seconds)

Publié dans Langage | Tagué | Laisser un commentaire

Les étiquettes en Java

English: A snippet of code in the Java program...

English: A snippet of code in the Java programming language written to illustrate syntax highlighting of keywords. (Photo credit: Wikipedia)

Les premières tasses de thé glacé passées, le tutoriel Java arrive sur les instructions de contrôle (branchement et boucle).  A l’époque où je développais couramment en Java, je n’utilisait que très peu les instruction break ou continue dans les boucles. L’utilisation d’étiquette était pour ainsi dire absente du code que je produisais. Pourquoi ? Tout d’abord parce qu’on a appris que les étiquettes (label) étaient utilisés dans d’autre langage pour faire des sauts (goto) et que cela était contraire à la programmation structurée, que l’on devait avoir un point d’entrée et un point de sortie unique, que cela simplifiait ainsi le code etc, etc. Et puis sans doute parce que la complexités des algorithmes de l’informatique de gestion ne nécessitait pas l’optimisation du flot de contrôle pour éviter des tours de boucle superflus.

Mais bien sûr si la performance est un critère comme par exemple en informatique financière, alors il vaut mieux sortir d’une boucle dès qu’on a fini le travail. Est-ce pour autant sacrifier le beauté du code et sa maintenabilité ? Non, car les étiquettes en Java ne servent qu’à nommer les blocs de boucles et on ne peut pas les mettre ailleurs pour faire des sauts dans tous les sens. Le code reste donc structuré. L’extrait de code suivant montre un exemple d’utilisation d’étiquette:

        premierNiveau:
        for (int i=0;i<100;i++){
            deuxiemeNiveau:
            for (int j=0;j<i*100;j++){
                boolean mustBreak = false;
                boolean mustContinueOutsideLoop = false;
                // code that decide if we must break or continue
                if (mustBreak){
                    break deuxiemeNiveau;
                }
                if (mustContinueOutsideLoop){
                    continue premierNiveau;
                }
                // very long running code here
            }
        }

Publié dans Langage | Tagué | Laisser un commentaire

Liste de paramètres variable des méthodes en Java

Depuis le JDK 1.5 qui fut une petite révolution il y a presque 10 ans de cela, il est possible de déclarer des méthodes ayant une liste de paramètre de taille variable afin de pouvoir appeler la méthode avec 1, 2 ou n’importe quel nombre de paramètre. Cela rappelait la fonction printf du langage C.

C’est en effet bien pratique d’appeler une méthode en lui passant le nombre d’argument que l’on veut. Une exemple canonique serait une méthode qui renvoie la concaténation des chaînes en paramètre.

String concat(String... arg){
    String concatenation = "";
    // corps de la méthode
    return concatenation;
}

Que l’on pourra appeler en faisant

String s = null;
s = concat("ma"," ","chaine"," ", "de", " ", "caractères"); // "ma chaine de caractère"

Il s’agit néanmoins d’un sorte de goodie du compilateur pour nous éviter de passer un tableau car c’est comme ça que l’on faisait avant. On déclarait la méthode comme suit:

String concat(String[] arg){
    // corps de la méthode
}

Puis lors de l’appel on s’efforçait de passe un tableau avec le surcoût de création de celui-ci:

String s = contact(new String[]{"ma"," ","chaine"," ","de"," ","caractères"});

Bien vu. On notera la limitation suivante, le paramètre variable doit être le dernier paramètre de la signature. Donc il ne peut y en avoir qu’un seul. On ne peut pas par exemple utiliser les points de suspension pour définir une méthode avec en premier lieu une liste d’un type et en second lieu une liste d’un autre type.

void neCompilePas(Object... lo, String... listStr) // le compilateur n'en veut pas
void compileBien(Object o, String... listStr) // on a le droit
Publié dans Langage | Tagué | Laisser un commentaire

Séparateur underscore dans littéral numérique en Java 7

Dès le début de la  lecture du tutoriel de Java 7 on remarque une nouvelle notation: l’underscore (blanc souligné) que l’on peut utiliser comme séparateur de groupe (millier, millions etc) afin d’augmenter la lisibilité des nombres écrits en valeur littérale. Cela donne :

int i = 0b1111_111001;

Qui est plus lisible que:

int i = 0b1111111001;
Publié dans Langage | Tagué | Laisser un commentaire

Salon les jeudis.com

Les jeudis.com organisent un salon 3 fois par an au CNIT de la Défense, regroupant une cinquantaine d’entreprise qui recrutent. C’est l’occasion pour les candidats de pouvoir se faire connaître directement auprès des recruteurs.  Aujourd’hui le salon se tenait dans ce contexte de morosité économique, alors c’est pour qui ce salon de recrutement ? Est-ce efficace ?

Tout d’abord peu entrain à me rendre dans un salon de recrutement car l’idée me rappelait une époque de crise en informatique, vers 2003 il me semble, où me rendant à un entretient du côté de Boulogne, je patientais dans la salle d’attente. Là, j’avais à côté de moi mes « compétiteurs » (une dizaine) pour reprendre le terme utilisé par un cabinet de recrutement: ils étaient tous costumés, encravatés et tiraient une mine d’enterrement. Alors l’idée de multiplier cela par 50 ne m’enchantait guère…

Une fois sur place, je retire mon guide du salon en échange d’un CV puis rentre sur la salon en feuilletant le dit guide. Ce dernier permet de connaître les entreprises présentes ainsi que leur besoin en recrutement: une telle cherche tel type de profil, une autre tel autre. Mais à peine que je dépassais l’accueil, je me fait alpaguer par une hôtesse qui me propose de lui remettre mon CV afin de le transmettre à l’ensemble des exposants. Bingo cela m’arrange d’autant plus que je n’ai pas pris un stock de CV avec moi.

Cependant puisque j’étais arrivé jusque là, je fis un tour des stands. Ce qui me frappe d’abord c’est la foule, il était 15h et les allées étaient bien encombrées. La crise peu-t-être ? Qui sont donc ces candidats ? De nombreux jeunes diplômés, certains pas encore diplômés à la recherche de stages. Devant certains stands de grosses SSII, d’impressionnantes queues s’étaient formées. Les candidats avaient l’air peu joyeux presque aussi morbides que les encravatés de 2003. Fuyant cette cohue, je me dirige alors vers un stand ayant moins d’affluence, petite SSII, et y laisse un CV. Plus loin je m’arrête au stand d’une société utilisatrice spécialiste du transport de personne. Je tente une approche détendue et suis frappé par l’incapacité de mon interlocuteur de cerner mon profil. Il a été obligé d’aller demander à son collègue pour finalement me dire que mon profil ne correspondait pas à ce qu’ils recherchent. Pourtant en regardant le guide du salon, si si et en allant sur le site web de l’entreprise on peut même y voir un poste en MOE avec mon profil. Je continue de déambuler dans les allées et croisent quelques candidats quadragénaires, ici un spécialiste du testing…  Finalement me restant une cartouche dans mon barillet à CV, je retourne au stand d’une banque. Là mon interlocuteur réagit correctement à mon approche détendue et me répond avec la même décontraction. Il semble intéressé  et en fin de compte je lui laisse mon dernier CV.

Plus de CV, la cohue, la chaleur, je quitte le salon avec une certaine satisfaction, celle de ne pas y avoir perdu mon temps. C’était une première pour moi et la prochaine fois s’il y a lieu, c’est promis, je viendrai avec quelques exemplaires de CV en plus.

Publié dans Actualité | Tagué , | Laisser un commentaire

Réapprendre Java

Duke, the Java Mascot, in the waving pose. Duk...

Duke, the Java Mascot, in the waving pose. Duke images are now Free Graphics see duke:Project Home Page for more details. (Photo credit: Wikipedia)

En informatique tout va vite, très vite même. C’est sans doute le métier ayant l’obsolescence des connaissances la plus grande. Du moins dans sa partie pratique. Dans mon cas, Java a été mon fond de commerce mais il est grand temps de réactualiser mes connaissances à ce sujet. Non pas par amour du code quoique… mais plutôt par approche pragmatique. Je l’ai d’ailleurs écrit sur ce blog avec un poil de provocation: « la technique d’abord ». Cela simplement pour dire que l’on ne peut réaliser que ce que la technique permet donc il faut maîtriser la technique si on veut réaliser de grande chose.

Pour se mettre jour commençons par le commencement. Un petit tout sur le site de Sun…. oooops, pardon, Oracle pour aller télécharger un Netbeans et un JDK…. 7. La 8 est dans les tuyaux mais bien connaître la version 7 (en faite 1.7) sera déjà un ravalement de façade parfait afin de faire du code au goût du jour et utilisant pleinement les possibilités offertes par la technique. Si l’on veut rester libre les versions OpenJDK peuvent être utilisées en lieu et place des JVM Oracle. D’ailleurs Oracle certifie les implémentation OpenJDK comme étant les références. Par défaut c’est le JDK 1.6 qui est installé sur Debian, mais un petit tour sur le gestionnaire de paquet permet de disposer d’un JDK 1.7. Pour Netbeans cependant la version qui est dans le dépôt Debian est la 7.0, donc un passage obligatoire par une installation manuelle si on veut la dernière Netbeans 7.3. Au choix aller chez netbean.org ou bien chez oracle pour télécharger l’ensemble JDK et Netbeans.

Une fois équipé des bons outils, nous nous lançons dans le réapprentissage. Pour cela les tutoriaux de Sun devenu Oracle me rappellent de lointains souvenirs quand sur les stations UltraSparc de la fac j’apprenais la javanaise en 1998. Heureusement que ma mémoire est encore bonne et me permet de sauter rapidement ce qui n’a pas changé. Pour les changements des billets d’humeurs viendrons s’ajouter à ce blog après une tasse de thé glacé.

Publié dans Langage | Tagué , , , | Laisser un commentaire