Vous êtes sur la page 1sur 46

Cours IHM-1

JavaFX
2 - Complments de
programmation
Jacques BAPST
jacques.bapst@hefr.ch

Prambule
Ce chapitre introduit de manire sommaire quelques lments de
programmation qui, faute de temps, n'ont pas t vus durant le
cours de programmation du premier semestre.
Ces lments sont cependant utiles, voire ncessaires dans le cadre
des programmes Java/JavaFX comportant des interfaces graphiques
(GUI).
La prsentation de ces concepts se limite aux lments essentiels qui
sont ncessaires dans le cadre du cours IHM-1.

On ne peut donc pas prtendre matriser ces concepts aprs cette


brve introduction. Elle devrait cependant suffire pour en
comprendre les mcanismes principaux .
Pour plus de dtail, il faut consulter l'abondante documentation
disponible (livres, web) sur ces sujets.

IHM-1 FX02

Jacques BAPST

numrations

IHM-1 FX01

Jacques BAPST

numrations [1]
En Java, le mot-cl enum permet de dfinir un type numr.
L'utilisation de enum dfinit une classe spciale (appele enum type)
qui hrite implicitement de java.lang.Enum et qui permet de
reprsenter un ensemble fixe de constantes (des champs qui sont
implicitement static et final) que l'on crit donc en majuscules.
Une variable de type numr ne peut prendre qu'une des valeurs
constantes dfinies pour le type considr (ou null ).
Exemple de dfinition du type numr EColor :
public enum EColor {RED, BLUE, GREEN, YELLOW}

EColor correspond au type numr. Les variables de ce type ne


peuvent prendre que les valeurs des constantes RED, BLUE, GREEN,
YELLOW ou la rfrence null.

IHM-1 FX02

Jacques BAPST

numrations [2]
Exemple d'utilisation du type EColor :
public class TestEColor {

public static void main(String[] args) {


EColor color = EColor.BLUE;
if (args.length > 0) color = EColor.RED;
System.out.println(color);
}
}

Le programme affichera BLUE (si aucun paramtre n'est pass au


lancement) ou RED (si au moins un paramtre est transmis au
lancement).

IHM-1 FX02

Jacques BAPST

numrations [3]
On peut s'pargner la notation prfixe (type.constante) en ajoutant
une importation statique des lments du type numr.
Exemple d'utilisation avec importation statique des constantes :
import static ex.chap02.EColor.*;
public class TestEColor {
public static void main(String[] args) {
EColor color = BLUE;
if (args.length > 0) color = RED;
System.out.println(color);
}
}

IHM-1 FX02

Jacques BAPST

numrations [4]
Pour tous les types numrs, une mthode statique values() est
implicitement dclare.
Elle retourne un tableau des constantes d'numration dans leur
ordre de dclaration.

Utile pour parcourir tous les lments d'un type numr :


public class TestEColor {
public static void main(String[] args) {
for (EColor color : EColor.values()) {
System.out.print(color + " ");
}
}
}

Le programme affichera :
RED BLUE GREEN YELLOW
IHM-1 FX02

Jacques BAPST

numrations [5]
Pour tous les types numrs, une mthode statique valueOf() est
implicitement dclare.
Cette mthode convertit une chane de caractres (passe en
paramtre) en un lment du type numr ou lve l'exception
IllegalArgumentException si la conversion n'est pas possible
(attention, la mthode est sensible la casse [minuscules/majuscules]).
Exemple de conversion d'une chane de caractres en un lment de
type numr :
public class TestEColor {
public static void main(String[] args) {
EColor yColor = EColor.valueOf("YELLOW");
System.out.println(yColor);
}
}

IHM-1 FX02

Jacques BAPST

numrations [6]
La mthode d'instance name() retourne un String correspondant
la reprsentation textuelle d'une variable de type numr (elle
se comporte de la mme manire que la mthode toString()).
Exemple :

String colName = yColor.name();

La mthode ordinal() retourne un int correspondant la position


de l'lment dans la dclaration d'une variable de type numr (la
numrotation commence zro).
Exemple :

int pos = yColor.ordinal();

// 3 for YELLOW

Une numration peut tre dfinie l'intrieur d'une classe ou dans


une unit de compilation spare (comme toute classe Java).
Une numration ne peut pas tre dfinie dans une mthode.
Il est possible d'ajouter des champs, des constructeurs et des
mthodes dans une classe de type enum.
Consulter la
documentation pour
plus de dtails.
IHM-1 FX02

Jacques BAPST

Gnricit
Types gnriques

IHM-1 FX01

Jacques BAPST

10

Types gnriques [1]


Un type gnrique est une classe ou une interface qui prend en
paramtre un type.
Prenons l'exemple d'une classe (non-gnrique) qui permet de
stocker et restituer un objet de type Integer :
public class IntegerBox {
private Integer anInt;
public Integer get() {
return anInt;
}
public void set(Integer value) {
anInt = value;
}
}

Que faudrait-il faire pour grer de la mme manire d'autres types


d'lments, par exemple Float, String, Point, Rectangle, ... ?
IHM-1 FX02

Jacques BAPST

11

Types gnriques [2]


Crer les variantes FloatBox, StringBox, ... ?
Crer une classe Box avec un champ de type Object ?
Une solution : crer une classe gnrique :
public class Box<T> {
private T obj;

public T get() {
return obj;
}
public void set(T obj) {
this.obj = obj;
}
}

La syntaxe className<type> permet de passer un type en paramtre


la classe. Dans l'exemple prcdent T peut tre considr comme
un paramtre formel qui reprsente un type (non-primitif)
quelconque.
IHM-1 FX02

Jacques BAPST

12

Types gnriques [3]


Lorsqu'on utilise la classe (comme type ou pour l'instancier), on
passe, entre < et >, le type effectif souhait :
public static void main(String[] args) {
Box<Integer> intBox = new Box<>();
// ou new Box<Integer>();
Box<String> strBox = new Box<>();
// ou new Box<String>();
Box<Point2D> p2dBox = new Box<>();
// ou new Box<Point2D>();

intBox.set(5);
strBox.set("Hello");
p2dBox.set(new Point2D(1.2, 3.4));
System.out.println(p2dBox.get());
}

On peut passer plus d'un type gnrique une classe ou une


interface en les sparant par une virgule :
public class TwoBox<T, U> { }

IHM-1 FX02

Jacques BAPST

13

Types gnriques [4]


Par convention, on utilise une seule lettre majuscule pour nommer
les paramtres formels de type.
La syntaxe <> (nomme diamond) peut tre utilise lorsque le
compilateur est capable de dterminer (d'infrer) le type en fonction
du contexte.
Les interfaces gnriques se basent exactement sur les mmes
conventions que celles des classes gnriques.
De nombreuses interfaces et classes de la plateforme Java
(notamment les Collections) utilisent la gnricit.
List<Point2D>

polygon = new ArrayList<>();

Pair<String, Integer> p1 = new Pair<>("Even", 8);


Pair<String, String> p2 = new Pair<>("Hi", "World");

IHM-1 FX02

Jacques BAPST

14

Types gnriques [5]


On peut aussi utiliser un type gnrique comme paramtre effectif
d'un type paramtr.
List< Pair<String, Integer> > pList = new ArrayList<>();
pList.add(new Pair<>("Small", 3));

Pour assurer la compatibilit du code crit avant le JDK 5.0, il est


possible d'omettre le paramtre effectif et de dclarer ce que l'on
nomme un raw type.
Dans ce cas, le type du paramtre est implicitement Object,
certaines limitations s'appliquent et des mises en garde peuvent
apparatre la compilation (unchecked conversions).
Box b = new Box();

// Raw type

b.set(8);
b.set("Hello");

// Autoboxing int => Integer => Object


// String => Object

IHM-1 FX02

Jacques BAPST

15

Types gnriques [6]


Pour dfinir un paramtre gnrique qui inclut une classe donne
ainsi que toutes ses sous-classes, on utilise la syntaxe :
< T extends type >
Par exemple :
public class ShapeBox<T extends Polygon> {
private T shape;
// Polygon or sub-class of Polygon
. . .
}

La formulation "extends type" doit tre prise ici dans un sens


gnral (extends or implements). Elle doit tre interprte comme :
La classe type ainsi que toutes ses sous-classes
Toute classe qui implmente l'interface type

ou

Avec cette syntaxe, on indique ainsi la "borne suprieure" du type


accept comme paramtre (upper bound).
IHM-1 FX02

Jacques BAPST

16

Types gnriques [7]


Le symbole '?' peut tre utilis comme caractre joker (wildcard)
dans diffrentes situations en lien avec les classes et interfaces
gnriques : type d'un paramtre, d'un champ, d'une variable locale,
etc.
Il reprsente un type (inconnu) quelconque.
Par exemple :
public static int countNonNull(List<?> list) {
int count = 0;
for (Object e : list) {
if (e != null) count++;
}
return count;
}

Dans cet exemple, seules les mthodes de l'interface List ou de


Object (sur les lments de la liste) peuvent tre utilises.
IHM-1 FX02

Jacques BAPST

17

Types gnriques [8]


Le caractre joker ? n'est pas quivalent Object.
List<?>

: une liste d'lments de n'importe quel type


List<Object> : une liste d'lments de type Object

Attention : Mme si (par ex.) Integer est une sous-classe de Object,


List<Integer> n'est pas une sous-classe de List<Object>
Object

Integer

IHM-1 FX02

List<Object>

List<Integer>

Object

List<Object>

Jacques BAPST

List<Integer>

18

< < <

C o mp l me nt

> > >

Types gnriques [9]


Lors de l'introduction de la gnricit dans le langage, la machine
virtuelle n'a pas t modifie. Une classe paramtre est compile
en une classe non paramtre.
Les variables de types sont donc perdues (oublies) aprs la
compilation (type erasure). Certaines oprations qui utilisent les
types gnriques l'excution (par exemple certains transtypages,
cration d'objets, utilisation de instanceof, ) ne sont donc pas
autorises et provoquent donc des erreurs (qui peuvent paratre
surprenantes) lors de la compilation.
public class Box<T> {
. . .

T temp = new T();


. . .

// Erreur la compilation

IHM-1 FX02

Jacques BAPST

19

Types gnriques [10]


Le caractre joker '?' (unbounded wildcard) peut galement tre
combin avec les mots-cls extends ou super pour dfinir des
bornes suprieures (upper bound) respectivement des bornes
infrieures (lower bound) pour les types accepts.
<? extends type> acceptera la classe type ainsi que toutes ses sous-

classes. Cette notation est galement valable pour toutes les classes
qui implmentent l'interface type.
[upper bounded]
<? super type> acceptera la classe type ainsi que toutes les classes
parentes de type.
[lower bounded]

Par exemple, pour ajouter des nombres une liste d'Integer, de


Number ou d'Object :
public static void addOneToTen(List<? super Integer> list) {
for (int i = 1; i <= 10; i++) {
list.add(i);
}
}
IHM-1 FX02

Jacques BAPST

20

Types gnriques [11]

< < <

C o mp l me nt

> > >

Quelques rgles et recommandations


L'utilisation du caractre joker <? > dpendra du rle que joue le
paramtre gnrique dans la mthode/fonction :
Paramtre 'in' (valeur utilise en entre de la mthode)
[Typiquement la mthode consomme les lments d'une collection]

Paramtre 'out' (valeur utilise en sortie, fournie par la mthode)


[Typiquement la mthode produit les lments d'une collection]

Paramtre 'in/out' (valeur utilise en entre et modifi par la mthode)

Il est recommand d'appliquer les rgles suivantes :


Tous les paramtres 'in' seront dfinis avec extends (upper-bound)
Tous les paramtres 'out' seront dfinis avec super (lower-bound)
Pour les paramtres 'in' accds exclusivement avec des mthodes de
Object, on utilisera un joker non born (unbounded-wildcard <?>)
Pour tous les paramtres 'in/out' on n'utilisera pas de joker
On n'utilisera par de joker comme type de retour
IHM-1 FX02

Jacques BAPST

21

Types gnriques [12]


Dans une classe (gnrique ou non) il est possible d'crire une
mthode gnrique (statique ou non-statique).
Syntaxiquement, le ou les types gnriques <> se placent, dans
l'en-tte, aprs les modificateurs et avant le type de retour.

Exemple :
public static <T> boolean contains(Box<T> box, T value) {
return box.get().equals(value);
}

En gnral, le paramtre gnrique n'est pas ncessaire lors de


l'invocation de la mthode, il est infr par le contexte.
Box.contains(fBox, 1.2f);

Box.<Float>contains(fBox, 1.2f);

IHM-1 FX02

// Syntaxe rarement ncessaire

Jacques BAPST

22

Annotations

IHM-1 FX01

Jacques BAPST

23

Annotations [1]
En Java, une annotation constitue une mtadonne que l'on peut
appliquer diffrents lments du code source.
Les annotations n'ont pas d'effet direct sur le fonctionnement des
instructions annotes.

Le caractre '@' indique au compilateur que l'identificateur qui suit


est une annotation.
Un exemple simple :
@Override
public String toString() {
//--- A String representation of current object
return "Circle: Radius=" + radius;
}

L'annotation @Override indique au compilateur que la mthode


redfinit une mthode hrite. Il pourra ainsi gnrer une erreur si
l'en-tte n'est pas correcte
IHM-1 FX02

Jacques BAPST

24

Annotations [2]
Sans l'annotation @Override le code fonctionne parfaitement (et de
manire identique) mais le programmeur ne serait pas averti qu'il cre
une nouvelle mthode d'instance (faute de frappe par ex.) alors qu'il
voulait redfinir une mthode d'une des classes parentes.
Une annotation peut inclure un ou plusieurs paramtres :
@Author (name = "Tryphon Tournesol",
date = "06.06.2016"
)
public class MyClass {
. . .
}

// Metadata about the class

Si l'annotation ne comporte qu'un seul paramtre dont le nom est


value, le nom peut tre omis :
@SuppressWarnings("unchecked")
public class MyClass {
. . . // Warnings about unchecked generic operations are suppressed
}
IHM-1 FX02

Jacques BAPST

25

Annotations [3]
Des annotations multiples peuvent tre attribues une mme
dclaration (une mme annotation peut galement tre rpte).
@Author (name = "Tryphon Tournesol")
@Author (name = "Archibald Haddock")
@EBook
public class MyClass {
. . .
}

// Repeating annotations
// Repeating annotations

Des annotations peuvent tre appliques des dclarations (classe,


champs, mthodes, etc.) mais galement lors de l'utilisation des types
(ces Type Annotations requirent l'installation d'un Checker Framework,
voir par exemple types.cs.washington.edu/checker-framework).
public void check(String name) {
@NonNull String loginName = name;
. . .
}
IHM-1 FX02

// Exception thrown if null

Jacques BAPST

26

Annotations [4]
Il existe un certain nombre d'annotations prdfinies, traites par le
compilateur ou par certains outils standard de la plateforme Java.
Exemples : @Deprecated, @Override, @SuppressWarnings,
@SafeVarargs, @FunctionalInterface,

Il est galement possible de dfinir ses propres annotations en


crivant une interface particulire (@interface )
import java.lang.annotation.Documented;
@Documented
// Will appear in Javadoc-generated documentation
public @interface ClassPreamble {
String
author();
// Parameter
String
date();
int
currentRevision() default 1; // Param. with default value
String
lastModifiedBy() default "N/A";
String[] reviewers();
// Array parameter
}

IHM-1 FX02

Jacques BAPST

27

Expressions Lambda
Rfrences de mthodes

IHM-1 FX01

Jacques BAPST

28

Expressions lambda [1]


Une expression lambda peut tre assimile une fonction anonyme
qui a potentiellement accs au contexte du code englobant.
Il s'agit essentiellement d'un bloc de code avec des paramtres et
qui est destin tre excut ultrieurement (une ou plusieurs fois).

Une expression lambda peut tre utilise pour implmenter une


interface fonctionnelle (interface ne comportant qu'une seule mthode
d'instance abstraite).
La syntaxe de base est :
ou

(parameters) ->
expression
(parameters) -> { statements; }

Remarque : Les parenthses autour des paramtres sont obligatoires


s'il y a zro (burger arrow : () -> ) ou plusieurs paramtres,
mais optionnelles s'il n'y en a qu'un seul et que le type est
infr (voir page suivante).
IHM-1 FX02

Jacques BAPST

29

Expressions lambda [2]


S'il y a plusieurs paramtres, il seront spars par des virgules.
Le type des paramtres peut tre indiqu explicitement ou tre
automatiquement dtermin par le compilateur (infr) en fonction
du contexte.

Le type de retour est toujours infr du contexte.


Exemples d'expressions lambda :
(int x, int y) -> { return x + y; }

// Types explicites, valeur de retour

(x, y) -> x + y

// Types infrs, valeur de retour

x -> x * x

// Type infr, valeur de retour

() -> 123

// Pas de paramtre, valeur de retour

s -> System.out.println(s)

// Type infr, pas de valeur de retour

() -> { for (int i=0; i<10; i++) doIt(); }

// Pas de valeur de retour

IHM-1 FX02

Jacques BAPST

30

Expressions lambda [3]


Par dfaut le code Java s'excute dans un thread appel main-thread
(cr automatiquement). Il est possible de crer d'autres threads qui
sont des fils d'excution (des processus lgers) permettant l'excution
parallle (ou pseudo-parallle) du code.
Une expression lambda peut tre utilise pour instancier l'interface
fonctionnelle Runnable (dfinie dans le package java.lang) qui
comporte la mthode abstraite public void run(); permettant
notamment d'excuter son code dans un thread spar.
Pour lancer du code dans un thread spar, il faut
Crer une instance de la classe Thread en passant l'objet Runnable
son constructeur : Thread t = new Thread(myRunnable);
Appeler la mthode start() de l'instance de Thread : t.start();

Une autre manire de faire : crer une sous-classe de Thread et


redfinir la mthode run(). Crer une instance et invoquer start().
IHM-1 FX02

Jacques BAPST

31

Expressions lambda [4]


Exemple : cration de deux threads l'aide d'expressions lambda.
public static void main(String[] args) {
Runnable rA = () -> { for (int i=0; i<100; i++)
System.out.println("A"+i); };
Runnable rB = () -> { for (int i=0; i<100; i++)
System.out.println("B"+i); };
Thread tA = new Thread(rA);
Thread tB = new Thread(rB);
tA.start();
tB.start();

// Cration du thread

// Lancement du thread : mthode run()

Un des rsultats
possibles l'excution
IHM-1 FX02

Jacques BAPST

A0
B0
B1
B2
A1
A2
B3
B4
B5
A3
B6
B7
B8
A4
B9
A5
A6
A7
A8
A9
A10
A11
B10
...

32

Interfaces fonctionnelles [1]


Les interfaces fonctionnelles jouent un rle important en lien avec
les expressions lambda. Plusieurs de ces interfaces sont prdfinies
(notamment dans le package java.util.function).
Deux exemples reprsentatifs (utiliss par la suite) :
// Supplier : Represents a supplier of results
//--------------------------------------------------------------------

@FunctionalInterface
public interface Supplier<T> {
T get(); // Gets a T type result
}
// Function : Represents a function that accepts one argument
//
and produces a result
//--------------------------------------------------------------------

@FunctionalInterface
public interface Function<T, R> {
R apply(T t); // Applies this function to the given argument
}
IHM-1 FX02

Jacques BAPST

33

Interfaces fonctionnelles [2]


Quelques interfaces fonctionnelles prdfinies
Interface
fonctionnelle

Type
Param

Type
Retour

Mthode
Description
abstraite

Runnable

void

run

Excute une action

Supplier<T>

get

Fournit une valeur de type T

Consumer<T>

void

accept

Consomme une valeur de type T

chain

void

accept

Consomme des valeurs de type T et U

chain

BiConsumer
T, U
<T, U>
Function

<T, R>

BiFunction
T, U
<T, U, R>

Autres
Mthodes

apply

Fonction avec un seul paramtre

compose,
andThen,
identity

apply

Fonction avec deux paramtres

andThen

UnaryOperator
T
<T>

apply

Oprateur unaire sur le type T

compose,
andThen,
identity

BinaryOperator
T, T
<T>

apply

Oprateur binaire sur le type T

andThen

IHM-1 FX02

Jacques BAPST

34

Interfaces fonctionnelles [3]


Quelques interfaces fonctionnelles prdfinies
Interface
fonctionnelle

Type
Param

Type
Retour

Predicate<T>

boolean test

Fonction boolenne (prdicat)

boolean test

Fonction boolenne avec 2 paramtres

BiPredicate
T, U
<T, U>

Mthode
Description
abstraite

Autres
Mthodes
and, or,
negate,
isEqual
and, or,
negate

Il existe galement un certain nombre d'interfaces fonctionnelles


prdfinies pour les types primitifs int, long et double. Exemples :
Interface
fonctionnelle

Type
Param

Type
Retour

Mthode
Description
abstraite

IntFunction<T>

int

apply

LongPredicate

long

boolean test

Fonction boolenne avec paramtre long

and, or,
negate

...

...

...

. . . et beaucoup d'autres . . .

...

IHM-1 FX02

...

Autres
Mthodes

Fonction avec paramtre int

Jacques BAPST

35

Rfrences de mthodes [1]


Une mthode existante peut tre utilise en tant qu'implmentation
de la mthode abstraite d'une interface fonctionnelle.
On dfinit pour cela une rfrence de mthode avec l'oprateur ::
Trois variantes existent :

Class :: staticMethodName
instance :: instanceMethodName
Class :: instanceMethodName
Exemples avec quivalences en expressions lambda :
Variante

Exemple

Lambda quivalent

Class::staticMethodName

String::valueOf

(s) -> String.valueOf(s)

instance::instanceMethodName

obj::toString

() -> obj.toString()

Class::instanceMethodName

String::toString

(s) -> s.toString()

Class::instanceMethodName

String::charAt

(s, i) -> s.charAt(i)

IHM-1 FX02

Jacques BAPST

36

Rfrences de mthodes [2]


Dans les deux premires variantes de syntaxe (Class::staticMethodName et
instance::instanceMethodName), la rfrence de mthode est quivalente
une expression lambda qui fournit les paramtres de la mthode.
Exemple variante 1 :
Supplier<Double> random = Math::random;
double result = random.get(); // Math.random();

Exemple variante 2 :
Random r = new Random();
Supplier<Double> random = r::nextDouble;
double result2 = random.get(); // r.nextDouble();

Ces deux exemples utilisent l'interface


fonctionnelle prdfinie Supplier<T>
dcrite dans les pages prcdente.

IHM-1 FX02

Jacques BAPST

37

Rfrences de mthodes [3]


Dans la troisime variante (Class::instanceMethodName), mme si on
mentionne le nom de la classe en prfixe, c'est bien une mthode
d'instance qui sera invoque. Le premier paramtre reprsente
l'objet sur lequel la mthode sera invoque.
Exemple variante 3 :
Function<String, Integer> fLen = String::length;
String s1 = "Hello";
String s2 = "World !";
int s1Len = fLen.apply(s1);
int s2Len = fLen.apply(s2);

// s1.length()
// s2.length()

Les rfrences de mthodes reprsentent donc une alternative aux


expressions lambda dans le cas o il n'y a qu'une seule et unique
mthode excuter.
Cela amliore gnralement la lisibilit et la clart du code.
IHM-1 FX02

Jacques BAPST

38

Rfrences de constructeurs [1]


Les rfrences de constructeurs sont semblables aux rfrences de
mthodes la diffrence que le nom de la "mthode" est new.
Les rfrences de constructeurs servent instancier une interface
fonctionnelle avec un constructeur compatible avec le contexte
d'utilisation.
Syntaxe :
Class :: new
Exemples avec quivalences en expressions lambda :
Syntaxe

Exemple

Lambda quivalent

Class::new

String::new

() -> new String()

Class::new

PointHolder::new

(p) -> new PointHolder(p)

IHM-1 FX02

Jacques BAPST

39

Rfrences de constructeurs [2]


Exemple d'utilisation de rfrences de constructeurs pour crer des
objets de type Button (un des constructeurs de la classe Button permet
de passer le libell du bouton en paramtre) :
Function<String, Button> btFactory = Button::new;
Button bOk
= btFactory.apply("Ok");
Button bQuit = btFactory.apply("Quit");

IHM-1 FX02

// new Button("Ok");
// new Button("Quit");

Jacques BAPST

40

Accs aux variables locales [1]


En plus des ventuels paramtres dfinis, des variables dclares
dans son corps et des champs statiques, une expression lambda
accs toutes les variables locales qui sont effectivement finales.
Une variable effectivement finale est une variable locale :
dclare avec le modificateur final
ou
non modifie aprs sa premire affectation

Une expression lambda qui utilise (capture) des variables locales


externes est parfois dsigne par le terme de capturing lambda.
On utilise galement le terme closure pour dsigner le bloc de code
de l'expression lambda accompagn de l'ensemble des variables
locales captures.

IHM-1 FX02

Jacques BAPST

41

Accs aux variables locales [2]


Dans l'exemple qui suit, les variables text et count ne sont pas
dfinies dans l'expression lambda. Ce sont des paramtres de la
mthode englobante capturs par l'expression lambda (variables
locales effectivement finales).
public static void repeatMessage(String text, int count) {
Runnable r = () -> { for (int i=0; i<count; i++) {
System.out.println(text);
Thread.yield(); // Gives a chance other threads to run
}
};
new Thread(r).start();
}

Ces variables restent accessibles malgr l'excution diffre du code.


public static void main(String[] args) {
repeatMessage("Hello", 100);
repeatMessage("Jane", 100);
}
IHM-1 FX02

Jacques BAPST

42

Stream

IHM-1 FX01

Jacques BAPST

43

Stream API [1]


Un stream reprsente une squence d'lments. Cette structure
supporte diffrents types d'oprations sur ces lments.
Les streams constituent un concept important en lien avec les
expressions lambda qui sont souvent utilises pour les manipuler.

L'essentiel des librairies (API) lies aux streams se trouve dans le


package java.util.stream avec notamment l'interface Stream<T>
Il est possible de crer un stream partir d'un tableau, d'une
collection, d'un gnrateur (Stream.generate()), d'un itrateur
(Stream.iterate()), d'un canal d'entre/sortie, etc.
Des manires classiques de crer un stream partir :
D'un tableau
: Arrays.stream(array)
D'une collection
: collection.stream()
D'une squence de valeurs : Stream.of(v1, v2, )

IHM-1 FX02

Jacques BAPST

44

Stream API [2]


Un exemple d'utilisation partir d'une liste de String sur laquelle
on applique une srie d'oprations :
public static void main(String[] args) {
List<String> myList =
Arrays.asList("a1", "a2", "b1", "c2", "d1", "c1");
myList.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);

Operation
pipeline

A l'excution, ce programme affichera :

C1
C2

Une expression lambda et deux rfrences de mthodes sont


utilises dans cet exemple pour dfinir certaines des oprations
effectues sur le flux.
IHM-1 FX02

Jacques BAPST

45

Stream API [3]


Les oprations appliques un stream peuvent tre :
Intermdiaires : elles retournent un stream ce qui permet un
enchanement d'oprations (pipeline, fluent API)
Terminales
: elles ne retournent rien (effectuent une opration)
ou retournent autre chose qu'un stream

Les oprations intermdiaires ne sont excutes que s'il y a une


opration terminale (laziness).
L'ordre dans lequel les oprations sont enchanes peut jouer un
rle important sur le rsultat et sur le nombre d'oprations
effectuer par le systme (typiquement, un filtrage est effectuer le
plus tt possible dans la chane des oprations).
Aprs avoir excut une opration terminale, un stream est ferm
et ne peut plus tre rutilis (si on veut le faire, il faut en crer un
nouveau).
IHM-1 FX02

Jacques BAPST

46

Vous aimerez peut-être aussi