Function et Lambda. Rémi Forax

Documents pareils
TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Page 1 sur 5 TP3. Thèmes du TP : l la classe Object. l Vector<T> l tutorial Interfaces. l Stack<T>

Java Licence Professionnelle CISII,

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Classe Interne, Anonyme & Enumération

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Cours 1 : Introduction. Langages objets. but du module. contrôle des connaissances. Pourquoi Java? présentation du module. Présentation de Java

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

Généralités sur le Langage Java et éléments syntaxiques.

ACTIVITÉ DE PROGRAMMATION

RMI le langage Java XII-1 JMF

Corrigé des exercices sur les références

Programmer en JAVA. par Tama

Package Java.util Classe générique

Java Licence Professionnelle Cours 7 : Classes et méthodes abstraites

Premiers Pas en Programmation Objet : les Classes et les Objets

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

P r ob lé m a t iq u e d e la g é n é r icit é. Pr in cip e d e la g é n é r icit é e n Ja v a ( 1 /3 )

Synchro et Threads Java TM

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

TP1 : Initiation à Java et Eclipse

Auto-évaluation Programmation en Java

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

as Architecture des Systèmes d Information

Machines Virtuelles. et bazard autour. Rémi Forax

Chapitre 10. Les interfaces Comparable et Comparator 1

Machines virtuelles fonctionnelles (suite) Compilation ML Java

Plan du cours. Historique du langage Nouveautés de Java 7

Design patterns. Design patterns - définition. Design patterns - avantages

Programmation Objet Java Correction

Lambda! Rémi Forax Univ Paris-Est Marne-la-Vallée

Cours 1 : La compilation

Tp 1 correction. Structures de données (IF2)

Corrigés des premiers exercices sur les classes

Java Licence Professionnelle CISII, Cours 2 : Classes et Objets

Langage Java. Classe de première SI

Programmation avec des objets : Cours 7. Menu du jour

Programmation Par Objets

LOG4430 : Architecture logicielle et conception avancée

TD/TP PAC - Programmation n 3

Programmation par les Objets en Java

PROGRAMMATION PAR OBJETS

Utiliser Java sans BlueJ

Serveur d'archivage 2007 Installation et utilisation de la BD exist

Encapsulation. L'encapsulation consiste à rendre les membres d'un objet plus ou moins visibles pour les autres objets.

Polymorphisme, la classe Object, les package et la visibilité en Java... 1

Une introduction à Java

TD Objets distribués n 3 : Windows XP et Visual Studio.NET. Introduction à.net Remoting

Gestion mémoire et Représentation intermédiaire

Cours 1: Java et les objets

Java - la plateforme

Java DataBaseConnectivity

2. Comprendre les définitions de classes

JAVA TD0. Prise en main du langage Environnement de base JAVA 1

Un ordonnanceur stupide

Gestion distribuée (par sockets) de banque en Java

Flux de données Lecture/Ecriture Fichiers

Utilisation d objets : String et ArrayList

Threads. Threads. USTL routier 1

Héritage presque multiple en Java (1/2)

Objets et Programmation. origine des langages orientés-objet

Exercices sur les interfaces

OpenPaaS Le réseau social d'entreprise

Chapitre VI- La validation de la composition.

Création d objet imbriqué sous PowerShell.

IFT287 Exploitation de base de données relationnelles et orientées objet. Laboratoire Mon premier programme Java en Eclipse

TP3. Mail. Attention aux fausses manoeuvres lors de ce TP vous pouvez endommager votre mail sur ouindose.

TP1. Outils Java Eléments de correction

INITIATION AU LANGAGE JAVA

Java 7 Les fondamentaux du langage Java

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

TD3: tableaux avancées, première classe et chaînes

RAPPELS SUR LES METHODES HERITEES DE LA CLASSE RACINE Object ET LEUR SPECIALISATION (i.e. REDEFINITION)

Initiation à JAVA et à la programmation objet.

JAVA 8. JAVA 8 - Les fondamentaux du langage. Les fondamentaux du langage Java. Avec exercices pratiques et corrigés JAVA 8 29,90.

Aide mémoire UML & Java 1ère partie : Introduction. marc.lemaire@u-cergy.fr

Programmation en Java IUT GEII (MC-II1) 1

Chapitre I Notions de base et outils de travail

Polycopié Cours Programmation Orientée Objet sous Java Programme : Filière SMI S5

Java 1.5 : principales nouveautés

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Environnements de développement (intégrés)

Programmation Réseau. Sécurité Java. UFR Informatique jeudi 4 avril 13

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

Support de cours et TD Programmation Orientée Objet

1 Définition d une classe en Java

Derrière toi Une machine virtuelle!

7 Développement d une application de MapReduce

Java Licence Professionnelle CISII,

Programme Compte bancaire (code)

30.avr.10 Présentation miniprojet. 9.mars.10 Cours 3 4.mai.10 Cours C mars.10 Cours 4 11.mai.10 Cours C++ 2

Java au cœur de la base de données Oracle

Bases de programmation. Cours 5. Structurer les données

Cours 14 Les fichiers

Desktop Intégration. Rémi Forax

RMI. Remote Method Invocation: permet d'invoquer des méthodes d'objets distants.

Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu.

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

Transcription:

Function et Lambda Rémi Forax forax@univ-mlv.fr

Calcul du minimum & maximum public static int min(int[] values) { if (values.length == 0) { throw new IllegalArgumentException(); int min = values[0]; for(int i = 1; i < values.length; i++) { min = Math.min(min, values[i); return min; Comment partager le code commun? public static int max(int[] values) { if (values.length == 0) { throw new IllegalArgumentException(); int max = values[0]; for(int i = 1; i < values.length; i++) { max = Math.max(max, values[i]); return max;

Il suffit d'utiliser un paramètre! private static final int OP_MIN = 1; private static final int OP_MAX = 2; public static int minormax(int[] values, int typeofop) { if (values.length == 0) { throw new IllegalArgumentException(); int value = values[0]; for(int i = 1; i < values.length; i++) { if (typeofop == OP_MIN) value = Math.min(value, values[i]); else { value = Math.max(value, values[i]); return min; Ahhhh, test sur un type!!!!

Rappel approche objet Chaque objet sait quelle est son opération 1 objet pour Math.min et 1 objet pour Math.max et on passe l'objet en paramètre de minormax Il faut donc 2 classes, et une interface qui permet de manipuler de façon commune des objets des deux classes

Solution objet interface IntBinaryOperator { public abstract int applyasint(int left, int right); public static int minormax(int[] values, IntBinaryOperator op) { if (values.length == 0) { throw new IllegalArgumentException(); int value = values[0]; for(int i = 1; i < values.length; i++) { value = op.applyasint(value, values[i]); return min;

Solution objet (suite) private static final IntBinaryOperator OP_MIN = new MinBinaryOperator(); private static final IntBinaryOperator OP_MAX = new MaxBinaryOperator(); class MinBinaryOperator implements IntBinaryOperator { public int applyasint(int left, int right) { return Math.min(left, right); class MaxBinaryOperator implements IntBinaryOperator { public int applyasint(int left, int right) { return Math.min(left, right); Solution cool mais verbeuse!

Functional interface Conceptuellement, une interface avec une seule méthode est équivalent à un pointeur de fonction en C On ajoute juste des noms Une interface fonctionnelle (functional interface) est une interface qui possède une seul méthode abstraite Dans l'exemple, IntBinaryOperator est une fonctional interface

Method reference En Java, une interface fonctionnelle permet de faire une conversion automatique d'une référence à une méthode vers l'interface fonctionnelle IntBinaryOperator op = Math::min; La syntaxe :: permet de référencé une méthode en indiquant le nom de la classe puis les nom de la méthode Le type des paramètres est calculée à partir de l'interface fonctionnelle

@FunctionalInterface Annotation qui permet de demander au compilateur de vérifier que l'interface possède bien une seule méthode abstraite marche comme @Override pratique pour documenter @FunctionalInterface interface IntBinaryOperator { public abstract int applyasint(int left, int right);

Comment le compilateur trouve la méthode référencée IntBinaryOperator op = Math::min; À partir de la fonctional interface, le compilateur trouve la méthode abstraite int applyasint(int left, int right) Il est déduit une signature fonctionnelle int(int,int) Le compilateur utilise la classe et le nom de la method reference Math.sin + int(int,int) = int Math.sin(int,int)

Et à l'exécution Le compilateur génére un code qui demande de créer un objet d'une classe qui implante l'interface fonctionelle et dont la méthode abstraite appel la méthode référencée La machine virtuelle crée à l'exécution la classe correspondante et une instance de celle-ci pour une même conversion, la classe utilisée est toujours la même

Exemple private static IntBinaryOperator getminop() { return Math::min; public static void main(string[] args) { IntBinaryOperator min1 = getminop(); System.out.println(min1.getClass()); // Lambda$$1 IntBinaryOperator min2 = getminop(); System.out.println(min2.getClass()); // Lambda$$1 System.out.println( min1.getclass() == min2.getclass()); // true

Solution Objet (en moins de lignes) @FunctionalInterface interface IntBinaryOperator { public abstract int applyasint(int left, int right); private static int minormax(int[] values, IntBinaryOperator op) { if (values.length == 0) { throw new IllegalArgumentException(); int value = values[0]; for(int i = 1; i < values.length; i++) { value = op.applyasint(value, values[i]); return min; public static int min(int[] values) { return minormax(values, Math::min); public static int min(int[] values) { return minormax(values, Math::max);

Et si on veut faire la somme? @FunctionalInterface interface IntBinaryOperator { public abstract int applyasint(int left, int right); private static int reduce(int[] values, IntBinaryOperator op) { if (values.length == 0) { throw new IllegalArgumentException(); int value = values[0]; for(int i = 1; i < values.length; i++) { value = op.applyasint(value, values[i]); return min; private static int add(int left, int right) { return left + right; public static int sum(int[] values) { return reduce(values, EnclosingClass::add); On doit écrire une méthode statique pour pouvoir faire la conversion

Lambda La syntaxe des lambdas est une syntaxe raccourcie qui permet d'écrire une fonction anonyme qui va être convertit en objet dont la classe implante une interface fonctionnelle public static int sum(int[] values) { return reduce(values, (int left, int right) -> left + right); Une lambda est une fonction anonymes

Inférence du type des paramètres Un peu comme pour les méthodes références, il est possible d'éviter de spécifier les types des paramètres public static int sum(int[] values) { return reduce(values, (left, right) -> left + right)); De la même façon, le compilateur trouve la signature fonctionnelle à partir de l'interface fonctionnelle

Syntaxe des lambdas Ils existents deux types de lambda Les lambdas expressions x -> x + 1 list.foreach(e -> System.out.println(e)); Les lambdas blocks x -> { System.out.println("hello lambda"); list.foreach(e -> { map.put(e.getname(), e); );

Syntaxe des lambdas Et la syntaxe varie suivant le nombre de paramètre Zéro paramètre pas de ';' () -> System;out.println("hello") () -> { System;out.println("hello"); Un paramètre x -> x + 1 ou (x) -> x + 1 les parenthèses ne sont pas obligatoire Deux paramètres et plus (x, y) -> x + y

Et compter le nombre de 3? private static int reduce(int[] values, IntBinaryOperator op) { if (values.length == 0) { throw new IllegalArgumentException(); int value = values[0]; for(int i = 1; i < values.length; i++) { value = op.applyasint(value, values[i]); return value; public static int countnumberof(int[] values, int value) { return reduce(values, (v, sum) - > sum + (v == value)? 1: 0); public static void main(string[] args) { int[] values =... System.out.println(countNumberOf(values, 3));

Lambda et variable locale Une lambda peut utiliser la valeur d'une variable locale int countnumberof(int[] values, int value) { return reduce(values, (v, sum) - > sum + (v == value)? 1: 0); Comme les variables locales peuvent mourrir avant que le code de la lambda soit exécutée, le compilateur copie la valeur à la création de la lambda

Durée de vie des variables locales Une variable locale peut être morte au moment où où le code de la lambda est exécutée Fin du scope IntBinaryOperation countbymultiple(int multiple) { return (v, sum) - > sum + multiple; public static void main(string[] args) { IntBinaryOperation binop = countbymultiple(2); binop.applyasint(2, 3); Utilisation du code la lambda

Capture de valeur de variable locale Lors de la conversion vers l'interface fonctionnelle, si une lambda utilise des variables locales, les valeurs de ces variables sont recopiées et envoyées en paramètre à la lambda Une lambda qui capture des valeurs de variable est différentes à chaque appel car la variable peut avoir une valeur différentes La lambda ne paut pas être constante Le compilateur ne permet que la capture de variable assigné une seule fois

Effectivement final Il n'est pas permis de capturer la valeur d'une variable dont la valeur change Le compilateur vérifie que la variable est déclarée final ou effectivement final IntBinaryOperation countbymultiple(int multiple) { multiple = 7; return (v, sum) - > sum + multiple; Capture impossible, la variable est pas effectivement final

Effectivement final Pour la même raison, il est impossible d'incrémenter ou de modifier une capture d'une variable à l'intérieur de la lambda IntBinaryOperation countbymultiple(int multiple) { multiple = 7; return (v, sum) - > sum + multiple++; Capture impossible, la variable est pas effectivement final

Capture de champs Il est aussi possible d'accéder au valeur des champs, dans ce cas c'est la valeur de this qui est capturé donc il est possible de modifier la valeur de champs dans une lambda public class Foo { private int multiple = 1; IntBinaryOperation cumulateby() { return (v, sum) - > sum + multiple++; // equivalent à (v, sum) - > sum + this.multiple++;

Method reference et capture Les méthodes références possèdent aussi un mécanisme de capture qui permet de capturer la valeur d'une réfrence sur laquelle sera cherchée la méthode ArrayList<String> list =... PrintStream out = System.out; list.foreach(out::println);

Functional interface prédéfinie Le package java.util.function contient des functional interfaces prédéfinies functionnal interfaces génériques void -> void j.l.runnable.run void -> T j.u.function.supplier<t>.get T -> void j.u.function.consumer<t>.accept T -> boolean j.u.function.predicate<t>.test T -> R j.u.function.function<t, R>.apply T -> T j.u.function.unaryoperator<t>.apply T,U -> R j.u.function.bifunction<t,u,r>.apply T,T -> T j.u.function.binaryoperator<t>.apply Spécialisées pour les types primitives int -> R j.u.function.intfunction<r>.apply T -> int j.u.function.tointfunction<t>.applyasint