4
4
4
x -> x+1 (x) -> x+1
() -> System.out.println("Hello world")
(x,y,z) -> x+y+z
@FunctionalInterface
@FunctionalInterface
public int e r face IFunc t i on {
int doFunct i o n ( int a, int b );
}
FunctionFactory doFunction
doFunction
pu blic class Fu n c t i o n F a c t o r y {
pu blic st atic IF u n ction getFunction A d d () {
re turn (a , b) -> a + b;
}
pu blic st atic IF u n ction getFunction M u l () {
re turn (a , b ) -> a * b;
}
}
pu blic class Main {
pu blic st atic voi d m ain ( Str i ng [] ar gs ) {
IFu n c tion mul = F u n c t i o n F a c t o r y . ge t F u n c t i onMul ();
Sy stem . out . p rint l n ( mul . doFunct i o n (3 , 7));
}
}
BinaryOperator<Integer>
apply
BinaryOperator<Integer>
im port java . u til . funct i on . Bi n a ryOperator ;
pu blic class Fu n c t i o n F a c t o r y {
pu blic st atic Bi nary O pera t or < Integer > ge t F u n ctionAdd () {
re turn (a , b ) -> a + b;
}
pu blic st atic Bi nary O pera t or < Integer > ge t F u n ctionMul () {
re turn (a , b ) -> a * b;
}
}
pu blic class Main {
pu blic st atic voi d m ain ( Str i ng [] ar gs ) {
Bi n aryO p erat o r < Integer > mul = Fu n c t i o n F a c t ory . ge t F u n c tionMul ();
Sy stem . out . p rint l n ( mul . app ly (3 , 7) );
}
}
Runnable void run
Supplier<T> T get
Consumer<T> T void accept andThen
BiConsumer<T, U> T, U void accept andThen
Function<T, R> T R apply compose
andThen
identity
BiFunction<T, U, R> T, U R apply andThen
UnaryOperator<T> T T apply compose
andThen
identity
BinaryOperator<T> T, T T apply andThen
Predicate<T> T boolean test and
or
negate
isEqual
BiPredicate<T, U> T, U boolean test and
or
negate
Stream Stream
filter(Predicate)
map() sorted()
count()
forEach() reduce() min() max() sum()
stream()
Int S t ream s trea m = In t S tream . of (7 , 8, 9, 10 , 11 , 12);
st ream . filte r (e - > e % 2 == 0)
. map (e -> e * e)
. forEa c h (e - > Syste m . out . prin t ln (e ));
e -> System.out.println(e)
System.out::println forEach()
Int s t ream s trea m = In t S tream . of (7 , 8, 9, 10 , 11 , 12);
IntP r e d i c ate isEv en = e - > e % 2 == 0;
IntUnary O p e r a t o r sq uare = e -> e * e;
st ream . filte r ( isEv en )
. map ( squa re )
. forEa c h ( Sys tem . out :: pr i ntln );
compose()
andThen()
Func tion < Integer , Integ er > plus 1 = i - > i + 1;
Func tion < Integ er , I nt eger > do u bleIt = i -> i * 2;
Func tion < Integ er , I nt eger > com p o s i tion = p lus 1 . andT h en ( doub l e It );
Sy stem . out . p rint l n ( co mpositi o n . appl y ( 5)) ; // r e sul t is 12
Function
plus1() doubleIt() compose()
andThen()
Function
Func tion < Integ er , I nt eger > com p o s i t i on2 =
com p o s i tion . and T hen ( plus 1 ). andT h en ( d o u bleIt );
Sy stem . out . p rint l n ( co m position2 . apply (5)) ; // resu lt is 26
pu blic st atic fina l Binar y Oper a tor < Integer > DIR E C TMUL =
(x , y) -> x * y;
pu blic enum Multip l y {
DIR E C TMUL {
pu blic In t eger apply ( Integ e r a, In tege r b ) {
re turn a * b ;
}
},
OT H E RMUL {
pu blic In t eger apply ( Integ e r a, In tege r b ) {
re turn ot h e rMul (a , b );
}
}
pu blic ab s t ract Int e ger apply ( I n tege r a , Int e ger b);
pr i vate st atic In t eger ot h e rMul ( In t eger a , Int e ger b) {
// oth er i m p l e m e n t a tion of mu l t i p lication
}
}
Sy stem . out . p rint l n ( Multi p l y . DIRECT M U L . app ly (3 , 4));
Sy stem . out . p rint l n ( Multi p l y . OTHER M UL . apply (3 , 4) );
apply
pu blic enum Multip l y im p l ements Bin a ryOp e rato r < Integer > {
DIR E C TMUL {
pu blic In t eger apply ( Integ e r a, In tege r b ) {
re turn a * b ;
}
},
OT H E RMUL {
pu blic In t eger apply ( Integ e r a, In tege r b ) {
re turn ot h e rMul (a , b );
}
};
pr i vate st atic In t eger ot h e rMul ( In t eger a , Int e ger b) {
// oth er i m p l e m e n t a tion of mu l t i p lication
}
}
Func tion < Integ er , I nt eger > plus 1 = i -> i + 1;
Sy stem . out . p rint l n ( Multip l y 2 . DI RECTM U L . andTh e n ( plu s1 ). ap ply (3 , 4)) ;
BinaryOperator<Integer>
pu blic enum Multip l y im p l ements Bin a ryOp e rato r < Integer > {
DIR E C TMUL (( a , b) -> a * b ) ,
OT H E RMUL ( (a , b ) -> o t herMu l (a , b ));
pr i vate Bi n aryO p erat o r < Integer > m u ltipli e r ;
Mu l t iply ( Bi n aryO p erat or < Integer > m ultipl i e r ){
this . mu l tiplie r = multip l i e r ;
}
pr i vate st atic In t eger ot h e rMul ( In t eger a , Int e ger b) {
// oth er i m p l e m e n t a tion of mu l t i p lication
}
pu blic In t eger apply ( Integ e r a, Integ e r b) {
re turn mul t i p lier . a ppl y (a , b);
}
}
apply
pu blic int e r face M u ltipl y {
Bi n aryO p erat o r < Integer > D IRECTM U L = ( a , b ) -> a + b ;
Bi n aryO p erat o r < Integer > O THER M U L = (a , b) -> ot herMu l (a , b );
pr i vate st atic In t eger ot h e rMul ( In t eger a , Int e ger b) {
// oth er i m p l e m e n t a tion of mu l t i p lication
}
}
Strategy
execute
Context executeStrategy
setStrategy
pu blic int e r face S t rateg y {
pu blic Y exe c ute (X x );
}
pu blic class St r ategy A impl e m e nts Strat e g y {
pu blic Y exe c ute (X x ) {
// i m p l e mentation for s t r ategy A
}
}
pu blic class St r ategy B impl e m e nts Strat e g y {
pu blic Y exe c ute (X x ) {
// i m p l e mentation for s t r ategy B
}
}
pu blic class Co ntex t {
pr i vate Str a tegy s t rateg y ;
pu blic void se t S trategy ( St r a tegy str a t egy ) {
this . st rate g y = st r a tegy ;
}
pu blic void ex e c u t e S t r a t e gy () {
...
y = st rateg y . execut e (x );
...
}
}
pu blic st atic voi d m ain ( Str i ng [] ar gs ) {
Co n text co n text = new Co ntex t ();
co n text . se t S t r a tegy ( new S t r a tegyA ());
co n text . execu t e S t r a t e g y ();
co n text . se t S t r a tegy ( new S t r a tegyB ());
co n text . execu t e S t r a t e g y ();
}
Strategies
execute Context
pu blic enum St r ategie s {
STR A T EGYA {
pu blic Y exe c ute (X x ) {
// i m p l e mentation of s t rateg y A
}
},
STR A T EGYB {
pu blic Y exe c ute (X x ) {
// i m p l e mentation of s t rateg y B
}
};
pu blic ab s t ract Y exec ute (X x );
}
pu blic class Co ntex t {
pr i vate Stra t e g ies strate g y ;
pu blic void se t S trategy ( Str a t e gies strat e gy ) {
this . st rate g y = st r a tegy ;
}
pu blic void ex e c u t e S t r a t e gy () {
...
y = st rateg y . execut e (x );
...
}
}
pu blic st atic voi d m ain ( Str i ng [] ar gs ) {
Co n text co n text = new Co ntex t ();
co n text . se t S t r a tegy ( Strat e g i es . STRATE G Y A );
co n text . execu t e S t r a t e g y ();
co n text . se t S t r a tegy ( Strat e g i es . STRATE G Y B );
co n text . execu t e S t r a t e g y ();
}
Strategies
pu blic int e r face S t rateg y {
void Y ex e cute ( X x )
}
pu blic class Co ntex t {
pr i vate Str a tegy s t rateg y ;
pu blic void se t S trategy ( St r a tegy str a t egy ) {
this . st rate g y = st r a tegy ;
}
pu blic void ex e c u t e S t r a t e gy () {
...
y = st rateg y . execut e (x );
...
}
}
pu blic int e r face S t r a tegies {
STR A T EGYA = (x ) -> ... // a lam b da e x p r e ssion us ing par a m eter x
STR A T EGYB = (x ) -> ... // anot h er l a mbd a ex p r e ssion usin g x
}
pu blic st atic voi d m ain ( Str i ng [] ar gs ) {
Co n text co n text = new Co ntex t ();
co n text . se t S t r a tegy ( Strat e g i es . STRATE G Y A );
co n text . execu t e S t r a t e g y ();
co n text . se t S t r a tegy ( Strat e g i es . STRATE G Y B );
co n text . execu t e S t r a t e g y ();
}
Strategy setStrategy
pu blic st atic voi d m ain ( Str i ng [] ar gs ) {
Co n text co n text = new Co ntex t ();
co n text . se t S t r a tegy ( Strat e g i es . STRATE G Y A );
co n text . execu t e S t r a t e g y ();
co n text . se t S t r a tegy ( Strat e g i es . STRATE G Y B );
co n text . execu t e S t r a t e g y ();
// cla ss C c o ntai n s metho d that m atc h in terfa c e St r ategy
co n text . se t S t r a tegy (C :: me thod );
co n text . execu t e S t r a t e g y ();
co n text . se t S t r a tegy (( x) - > d o S o m e t h in g C o m p l e t e l y D if f e r e n t ( x ));
co n text . execu t e S t r a t e g y ();
}
Strategies
4
4
Strategy
4
templateMethod
primitiveOperation1 primitiveOperation2
ClassA ClassB
templateMethod
pu blic ab s t ract cl ass Abst r a c t C l a s s {
pu blic final void te m p lateMethod () {
...
primitiveOperation1 ();
...
primitiveOperation2 ();
...
}
pro t e cted a b strac t void pr i m i t i v e O p e r a t i o n 1 ();
pro t e cted a b strac t void pr i m i t i v e O p e r a t i o n 2 ();
}
pu blic class Class A exten d s Ab s t r a c t Class {
pro t e cted void pr i m i t i v e O p e r a t i o n 1 () {
// i m p l e mentation
}
pro t e cted void pr i m i t i v e O p e r a t i o n 2 () {
// i m p l e mentation
}
}
pu blic class Class B exten d s Ab s t r a c t Class {
pro t e cted void pr i m i t i v e O p e r a t i o n 1 () {
// i m p l e mentation
}
pro t e cted void pr i m i t i v e O p e r a t i o n 2 () {
// i m p l e mentation
}
}
pu blic st atic voi d m ain ( Str i ng [] ar gs ) {
Abst r a c t C l a s s class 1 = new Clas sA () ;
cl ass1 . te m p l a t e M e t h o d ();
Abst r a c t C l a s s class 2 = new Clas sB () ;
cl ass2 . te m p l a t e M e t h o d ();
}
templateMethod
Hooks
templateMethod
pu blic class Te m p l a t e C lass {
pr i vate Ho oks hook s ;
pu blic Templa t e C l a s s ( Hoo ks h ook s ) {
this . hooks = h ook s ;
}
pu blic final void te m p lateMethod () {
...
ho oks . primitiveOperation1 ();
...
ho oks . primitiveOperation2 ();
...
}
}
pu blic enum Hoo ks {
HO OKSA {
pu blic void pr i m i t i v e O p e r a t i o n 1 () {
// i m p l e mentation
}
pu blic void pr i m i t i v e O p e r a t i o n 2 () {
// i m p l e mentation
}
},
HO OKSB {
pu blic void pr i m i t i v e O p e r a t i o n 1 () {
// i m p l e mentation
}
pu blic void pr i m i t i v e O p e r a t i o n 2 () {
// i m p l e mentation
}
};
pu blic ab s t ract void primitiveOperation1 ();
pu blic ab s t ract void primitiveOperation2 ();
}
pu blic st atic voi d m ain ( Str i ng [] ar gs ) {
Temp l a t e C l a s s class 1 = new Te m p l a t eClass ( H ook s . HOO K SA );
cl ass1 . te m p l a t e M e t h o d ();
Temp l a t e C l a s s class 2 = new Te m p l a t eClass ( H ook s . HOO K SB );
cl ass2 . te m p l a t e M e t h o d ();
}
CommandA CommandB
execute
pu blic class In voke r {
pr i vate Co m mand com mand ;
pu blic void regist e r ( Comma n d comma n d ) {
this . comma n d = co mman d ;
}
pu blic void reque s t () {
co m mand . ex ecut e ();
}
}
pu blic int e r face C o mman d {
void ex ecut e ();
}
pu blic class Co mmand A im p l e m ents C o mman d {
pr i vate Rec e iver r e ceive r ;
pu blic Co m m andA ( Re c eiver rec e iver ) {
this . re ceiv e r = re c e iver ;
}
pu blic void execu t e () {
re c e iver . ac t ion1 ();
}
}
pu blic class Co mmand B im p l e m ents C o mman d {
pr i vate Rec e iver r e ceive r ;
pu blic Co m m andB ( Re c eiver rec e iver ) {
this . re ceiv e r = re c e iver ;
}
pu blic void execu t e () {
re c e iver . ac t ion2 ();
}
}
pu blic class Re ceive r {
pu blic void actio n 1 () {
// i m p l e mentation
}
pu blic void actio n 2 () {
// i m p l e mentation
}
}
pu blic st atic voi d m ain ( Str i ng [] ar gs ) {
Re c e iver rece i v er1 = new Recei v er ();
Re c e iver rece i v er2 = new Recei v er ();
In v oker in v oker = new In voke r ();
in v oker . re g ister ( new C o mmand A ( re c eiver 1 ));
in v oker . ex ecut e ();
in v oker . re g ister ( new C o mmand B ( re c eiver 2 ));
in v oker . ex ecut e ();
in v oker . re g ister ( new C o mmand A ( re c eiver 2 ));
in v oker . ex ecut e ();
}
pu blic class In voke r {
pr i vate Co m mand com mand ;
pr i vate Rec e iver r e ceive r ;
pu blic void regist e r ( Receiv e r recei ver , Co mman d co mman d ) {
this . re ceiv e r = re c e iver ;
this . comma n d = co mman d ;
}
pu blic void reque s t () {
co m mand . ex ecut e ( re ceiv e r );
}
}
pu blic enum Comma n d {
CO M M AND1 {
pu blic void execu t e ( Recei v er receiv e r ) {
re c e iver . ac t ion1 ();
}
},
CO M M AND2 {
pu blic void execu t e ( Recei v er receiv e r ) {
re c e iver . ac t ion2 ();
}
};
pu blic ab s t ract void ex ecut e ( Receiv e r re ceive r );
}
pu blic class Re ceive r {
pu blic void actio n 1 () {
// i m p l e mentation
}
pu blic void actio n 2 () {
// i m p l e mentation
}
}
pu blic st atic voi d m ain ( Str i ng [] ar gs ) {
Re c e iver rece i v er1 = new Recei v er ();
Re c e iver rece i v er2 = new Recei v er ();
In v oker in v oker = new In voke r ();
in v oker . re g ister ( receiv er1 , Co m mand . CO MMAND 1 );
in v oker . ex ecut e ();
in v oker . re g ister ( receiv er2 , Co m mand . CO MMAND 2 );
in v oker . ex ecut e ();
in v oker . re g ister ( receiv er2 , Co m mand . Co mmand A );
in v oker . ex ecut e ();
}
::
pu blic int e r face C o mman d {
void ex ecut e ();
}
pu blic class In voke r {
pr i vate Co m mand com mand ;
pu blic void regist e r ( Comma n d comma n d ) {
this . comma n d = co mman d ;
}
pu blic void execu t e () {
co m mand . ex ecut e ();
}
}
pu blic class Re ceive r {
pu blic void actio n 1 () {
// i m p l e mentation
}
pu blic void actio n 2 () {
// i m p l e mentation
}
}
pu blic st atic voi d m ain ( Str i ng [] ar gs ) {
Re c e iver rece i v er1 = new Recei v er ();
Re c e iver rece i v er2 = new Recei v er ();
In v oker in v oker = new In voke r ();
in v oker . re g ister ( re c e iver1 :: ac t ion1 );
in v oker . ex ecut e ();
in v oker . re g ister ( re c e iver2 :: ac t ion2 );
in v oker . ex ecut e ();
in v oker . re g ister ( re c e iver2 :: ac t ion1 );
in v oker . ex ecut e ();
in v oker . re g ister (() - > S yste m . out . pri n tln (" ex tra co m mand " ));
in v oker . ex ecut e ();
in v oker . re g ister ( new R e ceive r () -> acti o n2 ()) ;
in v oker . ex ecut e ();
}
ComponentA ComponentB
addedBehavior
Decorator
pu blic int e r face C o m ponen t {
void op e r ation ();
}
pu blic class Co m p onentA imple m e n ts Co mpone n t {
pu blic void op erati o n () {
// i m p l e mentation
}
}
pu blic class Co m p onentB imple m e n ts Co mpone n t {
pu blic void op erati o n () {
// i m p l e mentation
}
}
pu blic ab s t ract cl ass De c o rator i m p lement s Comp o n ent {
pr i vate Com p o nent compon e n t ;
pro t e cted D e c orato r ( Co m p onent comp o n ent ) {
this . co mponen t = comp o n ent ;
}
pu blic void op erati o n () {
com p o nent . o p e ratio n ();
}
}
pu blic class De c o ratorA ext e nds D e c orato r {
pro t e cted D e c o ratorA ( Com p o nent c o m ponen t ) {
su per ( co m ponen t );
}
pu blic void op erati o n () {
su per . op e ratio n (); // al so p ossib l e in rever se ord er
this . ad d e d B e h avior (); // so fi rst a d d e d Bahavior
}
pr i vate void ad d e d B e h avior () {
// i m p l e mentation
}
}
pu blic class De c o ratorB ext e nds D e c orato r {
pro t e cted D e c o ratorB ( Com p o nent c o m ponen t ) {
su per ( co m ponen t );
}
pu blic void op erati o n () {
su per . op e ratio n ();
this . ad d e d B e h avior ();
}
pr i vate void ad d e d B e h avior () {
// i m p l e mentation
}
}
pu blic st atic voi d m ain ( Str i ng [] ar gs ) {
Com p o nent comp = new Decora t o r B (
new Decorat o r B (
new Decorat o r A (
new Compone n t A ()))) ;
comp . op eratio n ();
}
Decoration
addedBehavior
Decorator
pu blic int e r face C o m ponen t {
void op e r ation ();
}
pu blic class Co m p onentA imple m e n ts Co mpone n t {
pu blic void op erati o n () {
// i m p l e mentation
}
}
pu blic class Co m p onentB imple m e n ts Co mpone n t {
pu blic void op erati o n () {
// i m p l e mentation
}
}
pu blic class De c orato r impl e m e nts Compon e n t {
pr i vate Com p o nent compon e n t ;
pr i vate Deco r a t ion de corati o n ;
pro t e cted D e c orato r ( De c o r ation deco rat ion , Com p o nent compo n e n t ) {
this . co mponen t = comp o n ent ;
this . de c oratio n = decora t i o n ;
}
pu blic void op erati o n () {
com p o nent . o p e ratio n ();
dec o r ator . a d d e d B e h avior ();
}
}
pu blic enum De c oratio n {
DEC O R A T IONA {
pu blic void ad d e d B e havior () {
// i m p l e mentation
}
},
DEC O R A T IONB {
pu blic void ad d e d B e havior () {
// i m p l e mentation
}
};
pu blic ab s t ract void ad d e d B e h a v ior ();
}
pu blic st atic voi d m ain ( Str i ng [] ar gs ) {
Com p o nent comp = new D e c o rator ( De c o r ation . D ECO RATI ONB ,
new Decor a t o r ( Decorat i o n . DECO RAT IONB ,
new Decor a t o r ( Decorat i o n . DECO RAT IONA ,
new Compone n t A ()))) ;
comp . op eratio n ();
}
Decorator
pu blic st atic voi d m ain ( Str i ng [] ar gs ) {
Com p o nent comp = new D e c o rator (
new Compone n t A () ,
Dec o r a tion . D ECORATI ONB ,
Dec o r a tion . D ECORATI ONB ,
Dec o r a tion . DECORA T I O N A );
comp . op eratio n ();
}
Decorator
pu blic class De c orato r impl e m e nts Compon e n t {
pr i vate Com p o nent compon e n t ;
pr i vate Deco r a t ion [] d e c o rations ;
pro t e cted D e c orato r ( Co m p onent compone nt ,
Dec o r a tion ... d e c o rations ) {
this . co mponen t = comp o n ent ;
this . de c o rations = d ecorati o n s ;
}
pu blic void op erati o n () {
com p o nent . o p e ratio n ();
for ( Decor a t i on d : de c o r a tions ) {
d. ad d e d B e h avior ();
}
}
}
java.io.Reader java.io.BufferedReader
addedBehavior
addedBehavior
Context
Strategy
Strategy StrategyA StrategyB
Function<P, R>
n n
Strategy
execute()
https://www.voxxed.com/2016/04/gang-fourpatterns-functional-
light-part-1/
https://www.voxxed.com/2016/05/gang-fourpatterns-functional-
light-part-2/
https://www.voxxed.com/2016/05/gang-fourpatterns-functional-
light-part-3/
https://www.voxxed.com/2016/05/gang-fourpatterns-functional-
light-part-4/