SlideShare uma empresa Scribd logo
1 de 95
Baixar para ler offline
Código funcional em Java:
Superando o hype
Eder Ignatowicz
Sr. Software Engineer
JBoss by Red Hat
Lambda Expressions 101
Dora
Bento
public Pug( String nome,
String color,
Integer size ) {
this.nome = nome;
this.color = color;
this.weight = size;
}
Pug dora = new Pug( "Dora", "abricot", 10 );
Pug bento = new Pug( "Bento", "abricot", 13 );
Pug jesse = new Pug( "Jesse", "black", 9 );
Requisito:
Filtrar todos os pugs de
cor “abricot" da lista
Filtrar todos os pugs de cor “abricot" da lista
private static List<Pug> filterAbricotPugs( List<Pug> pugs ) {
List<Pug> abricots = new ArrayList<>();
for ( Pug pug : pugs ) {
if ( pug.getColor().equals( "abricot" ) ) {
abricots.add( pug );
}
}
return abricots;
}
List<Pug> pugs = Arrays.asList( dora, bento, jesse );
List<Pug> abricot = filterAbricotPugs( pugs );
Pug{nome='Dora', color='abricot', weight=10}
Pug{nome='Bento', color='abricot', weight=13}
Novo Requisito: :)
Filtrar todos os pugs de cor “black" da lista
private static List<Pug> filterAbricotPugs( List<Pug> pugs ) {
List<Pug> abricots = new ArrayList<>();
for ( Pug pug : pugs ) {
if ( pug.getColor().equals( "abricot" ) ) {
abricots.add( pug );
}
}
return abricots;
}
private static List<Pug> filterBlackPugs( List<Pug> pugs ) {
List<Pug> abricots = new ArrayList<>();
for ( Pug pug : pugs ) {
if ( pug.getColor().equals( "black" ) ) {
abricots.add( pug );
}
}
return abricots;
}
Filtrar todos os pugs de cor “black" da lista
private static List<Pug> filterPugByColor( List<Pug> pugs,
String color ) {
List<Pug> coloured = new ArrayList<>();
for ( Pug pug : pugs ) {
if ( pug.getColor().equals( color ) ) {
coloured.add( pug );
}
}
return coloured;
}
List<Pug> black = filterPugByColor( pugs, "black" );
black.forEach( System.out::println );
Pug{nome='Jesse', color='black', weight=9}
Novo Requisito: :)
Filtrar todos os pugs com sobrepeso (>10 kg)
Filtrar todos os pugs com sobrepeso (>10 kg)
private static List<Pug> filterPugBySize( List<Pug> pugs,
int size ) {
List<Pug> fat = new ArrayList<>();
for ( Pug pug : pugs ) {
if ( pug.getWeight() > size ) {
fat.add( pug );
}
}
return fat;
}
List<Pug> fat = filterPugBySize( pugs, 10 );
fat.forEach( System.out::println );
Pug{nome='Bento', color='abricot', weight=13}
private static List<Pug> filterPugs( List<Pug> pugs,
String color,
int weight,
boolean flag ) {
List<Pug> result = new ArrayList<>();
for ( Pug pug : pugs ) {
if ( ( flag && pug.getColor().equals( color ) ) ||
( !flag && pug.getWeight() > weight ) ) {
result.add( pug );
}
}
return result;
}
Refatorador :D
List<Pug> result = filterPugs(pugs, "black", 0, true);
List<Pug> result1 = filterPugs(pugs, "", 10, false);
Behavior Parametrization
Behavior Parametrization
public interface PugPredicate {
boolean test(Pug pug);
}
class BlackPugPredicate implements PugPredicate{
@Override
public boolean test( Pug pug ) {
return pug.getColor().equals( "black" );
}
}
class FatPugPredicate implements PugPredicate{
@Override
public boolean test( Pug pug ) {
return pug.getWeight()>10;
}
}
Predicate
List<Pug> black = filterPug( pugs,
new BlackPugPredicate() );
List<Pug> fat = filterPug( pugs,
new FatPugPredicate() );
fat.forEach( System.out::println );
Pug{nome='Bento', color='abricot',
weight=13}
Classes anônimas
<3
List<Pug> abricotsNotFat =
filterPug( pugs, new PugPredicate() {
@Override
public boolean test( Pug pug ) {
return pug.getColor().equals( "abricot" )
&& pug.getWeight() <= 10;
}
} );
abricotsNotFat.forEach( System.out::println );
Pug{nome='Dora', color='abricot', weight=10}
Expressões Lambda
<3
(Pug p1,Pug p2) -> p1.getWeight().compareTo(p2.getWeight())
Parâmetros
do
Lambda
"Arrow"
Corpo
do
Lambda
class BlackPugPredicate implements PugPredicate{
@Override
public boolean test( Pug pug ) {
return "black".equals( pug.getColor() ) );
}
}
blacks = filterPug( pugs, new BlackPugPredicate() );
blacks = filterPug( pugs,
(Pug pug) ->"black".equals( pug.getColor() ) );
Posso modificar mais um pouco?
public interface Predicate<T>{
boolean test(T t);
}
public static <T> List<T> filter
(List<T> list, Predicate<T> p){
List<T> result = new ArrayList<>();

for(T e: list){
if(p.test(e)){
result.add(e);
}
}
return result;
}
List<Pug> blacks =
filter( pugs,
(Pug pug) ->"black".equals( pug.getColor() ) );
List<Integer> pares =
filter(numbers,
i -> i % 2 == 0);
Predicate<Pug> fatPredicate = d -> d.getWeight() > 9;
Predicate<Pug> abricotPredicate1 =
d -> d.getColor().equalsIgnoreCase( "abricot" );
Predicate<Pug> abricotAndFat =
abricotPredicate.and( fatPredicate );
@FunctionalInterface
public interface Predicate<T>{
boolean test(T t);
}
public static <T> List<T> filter(List<T> list, Predicate<T> p) {
List<T> results = new ArrayList<>();
for(T s: list){
if(p.test(s)){
results.add(s);
}
}
return results;
}
Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty();
List<String> nonEmpty = filter(listOfStrings, nonEmptyStringPredicate);
Predicate
Consumer
public class ShoppingCartTest {
ShoppingCart cart;
@Before
public void setup() {
Item item1 = new Item( 10 );
Item item2 = new Item( 20 );
cart = new ShoppingCart( Arrays.asList( item1, item2 ) );
}
@Test
public void totalTest() {
cart.pay( ShoppingCart.PaymentMethod.CREDIT ) );
}
}
public class ShoppingCart {
private List<Item> items;
public ShoppingCart( List<Item> items ) {
this.items = items;
}
public void pay( PaymentMethod method ) {
int total = cartTotal();
if ( method == PaymentMethod.CREDIT ) {
System.out.println( “Pay with credit “ + total );
} else if ( method == PaymentMethod.MONEY ) {
System.out.println( “Pay with money “ + total );
}
}
private int cartTotal() {
return items
.stream()
.mapToInt( Item::getValue )
.sum();
}
…
}
public interface Payment {
public void pay(int amount);
}
public class CreditCard implements Payment {
@Override
public void pay( int amount ) {
System.out.println( "Pay with Credit: “+ amount);
}
}
public class Money implements Payment {
@Override
public void pay( int amount ) {
System.out.println( "Pay with Money: “+ amount);
}
public class ShoppingCart {
…
public void pay( Payment method ) {
int total = cartTotal();
method.pay( total );
}
private int cartTotal() {
return items
.stream()
.mapToInt( Item::getValue )
.sum();
}
}
Strategy“Definir uma família de algoritmos, encapsular cada uma
delas e torná-las intercambiáveis. Strategy permite que o
algoritmo varie independentemente dos clientes que o
utilizam” GAMMA, Erich et al.
public interface Payment {
public void pay(int amount);
}
public class CreditCard implements Payment {
@Override
public void pay( int amount ) {
System.out.println( "make credit
payment logic" );
}
}
public class Money implements Payment {
@Override
public void pay( int amount ) {
System.out.println( "make money
payment logic" );
}
}
public class DebitCard implements Payment {
@Override
public void pay( int amount ) {
System.out.println( "make debit
}
}
public void totalTest() {
assertEquals( 30, cart.pay( new CreditCard() ) );
assertEquals( 30, cart.pay( new Money() ) );
assertEquals( 30, cart.pay( new DebitCard() ) );
}
}
public class ShoppingCart {
…
public void pay( Consumer<Integer> method ) {
int total = cartTotal();
method.accept( total );
}
…
}
public void pay( Payment method ) {
int total = cartTotal();
method.pay( total );
}
public class ShoppingCart {
…
public void pay( Consumer<Integer> method ) {
int total = cartTotal();
method.accept( total );
}
…
}
public void totalTest() {
cart.pay( amount ->
System.out.println( "Pay with Credit: " + amount ) );
cart.pay( amount ->
System.out.println( "Pay with Money: " + amount ) );
cart.pay( amount ->
System.out.println( "Pay with Debit: " + amount ) );
}
public class PaymentTypes {
public static void money( int amount ) {
System.out.println( "Pay with Money: " + amount );
}
public static void debit( int amount ) {
System.out.println( "Pay with Debit: " + amount );
}
public static void credit( int amount ) {
System.out.println( "Pay with Credit: " + amount );
}
}
public void totalTest() {
cart.pay( PaymentTypes::credit );
cart.pay( PaymentTypes::debit );
cart.pay( PaymentTypes::money );
}
public class ShoppingCart {
…
public void pay( Consumer<Integer> method ) {
int total = cartTotal();
method.accept( total );
}
…
}
Strategy
Functions
List<Pug> pugs = Arrays.asList( dora, bento, jesse );
Function<Pug, String> extractName = pug -> pug.getName();
List<String> nomes = pugs.stream()
.map( extractName )
.collect( Collectors.toList() );
print( nomes );
Dora
Bento
Jesse
List<Pug> pugs = Arrays.asList( dora, bento, jesse );
Function<Pug, String> extractName = pug -> pug.getName();
List<String> nomes = pugs.stream()
.map( extractName )
.collect( Collectors.toList() );
print( nomes );
UnaryOperator<String> upper = s -> s.toUpperCase();
List<Pug> pugs = Arrays.asList( dora, bento, jesse );
Function<Pug, String> extractName = pug -> pug.getName();
List<String> nomes = pugs.stream()
.map( extractName )
.collect( Collectors.toList() );
print( nomes );
UnaryOperator<String> upper = s -> s.toUpperCase();
List<String> nomesUpper = pugs.stream()
.map( extractName.andThen( upper ) )
.collect( Collectors.toList() );
print( nomesUpper );
public class Item {
private int price;
public Item( int price ) {
this.price = price;
}
public int getPrice() {
return price;
}
}
Extras
Envio
Impostos
Embalagem
public interface Item {
int getPrice();
}
public class Book implements Item {
private int price;
public Book( int price ) {
this.price = price;
}
@Override
public int getPrice() {
return price;
}
}
public abstract class ItemExtras implements Item {
private Item item;
public ItemExtras( Item item ) {
this.item = item;
}
@Override
public int getPrice() {
return item.getPrice();
}
}
public class InternationalDelivery extends ItemExtras {
public InternationalDelivery( Item item ) {
super( item );
}
@Override
public int getPrice() {
return 5 + super.getPrice();
}
}
public class GiftPacking extends ItemExtras {
public GiftPacking( Item item ) {
super( item );
}
@Override
public int getPrice() {
return 15 + super.getPrice();
}
}
public static void main( String[] args ) {
Item book = new Book( 10 );
book.getPrice(); //10
Item international = new InternationalDelivery( book );
international.getPrice(); //15
}
public static void main( String[] args ) {
Item book = new Book( 10 );
book.getPrice(); //10
Item internationalGift = new GiftPacking(
new InternationalDelivery( book ) );
internationalGift.getPrice(); //30
}
public static void main( String[] args ) {
Item book = new Book( 10 );
book.getPrice(); //10
Item internationalGiftWithTaxes = new InternacionalTaxes(
new GiftPacking(
new InternationalDelivery( book );
internationalGiftWithTaxes.getPrice(); //80
}
}
Decorator“Dinamicamente, agregar responsabilidades
adicionais a objetos. Os Decorators fornecem uma
alternativa flexível ao uso de subclasses para
extensão de funcionalidades.”
GAMMA, Erich et al.
new BufferedReader(new FileReader(new File("some.file")));
public static void main( String[] args ) {
Item book = new Item( 10 );
book.getPrice(); //10
Function<Integer, Integer> giftPacking = value -> value + 15;
giftPacking.apply( book.getPrice() ); //25
}
public static void main( String[] args ) {
Item book = new Item( 10 );
book.getPrice(); //10
Function<Integer, Integer> giftPacking = value -> value + 15;
giftPacking.apply( book.getPrice() ); //25
Function<Integer, Integer> intTaxes = value -> value + 50;
intTaxes.apply( book.getPrice() ); //60
}
public static void main( String[] args ) {
Item book = new Item( 10 );
book.getPrice(); //10
Function<Integer, Integer> giftPacking = value -> value + 15;
giftPacking.apply( book.getPrice() ); //25
Function<Integer, Integer> intTaxes = value -> value + 50;
intTaxes.apply( book.getPrice() ); //60
giftPacking.andThen( intTaxes ).apply( book.getPrice() ); //75
}
public class Item {
private int price;
private Function<Integer, Integer>[] itemExtras = new Function[]{};
public Item( int price ) {
this.price = price;
}
public Item( int price, Function<Integer, Integer>... itemExtras) {
this.price = price;
this.itemExtras = itemExtras;
}
public int getPrice() {
int priceWithExtras = price;
for ( Function<Integer, Integer> itemExtra : itemExtras ) {
priceWithExtras = itemExtra.apply( priceWithExtras );
}
return priceWithExtras;
}
public void setItemExtras( Function<Integer, Integer>... itemExtras ) {
this.itemExtras = itemExtras;
}
}
public static void main( String[] args ) {
Item book = new Item( 10 );
Function<Integer, Integer> giftPacking = value -> value + 15;
Function<Integer, Integer> intTaxes = value -> value + 50;
book.setItemExtras( giftPacking, intTaxes );
book.getPrice(); //75
}
public static void main( String[] args ) {
Item book = new Item( 10 );
Function<Integer, Integer> giftPacking = value -> value + 15;
Function<Integer, Integer> intTaxes = value -> value + 50;
book.setItemExtras( giftPacking, intTaxes );
book.getPrice(); //75
}
public class Packing {
public static Integer giftPacking( Integer value ) {
return value + 15;
}
//other packing options here
}
public class Taxes {
public static Integer internacional( Integer value ) {
return value + 50;
}
//other taxes here
}
public static void main( String[] args ) {
Item book = new Item( 10, Packing::giftPacking,
Taxes::internacional );
book.getPrice(); //75
}
public class Item {
private int price;
private Function<Integer, Integer>[] itemExtras = new Function[]{};
public Item( int price ) {
this.price = price;
}
public Item( int price, Function<Integer, Integer>... itemExtras) {
this.price = price;
this.itemExtras = itemExtras;
}
public int getPrice() {
int priceWithExtras = price;
for ( Function<Integer, Integer> itemExtra : itemExtras ) {
priceWithExtras = itemExtra.apply( priceWithExtras );
}
return priceWithExtras;
}
public void setItemExtras( Function<Integer, Integer>... itemExtras ) {
this.itemExtras = itemExtras;
}
}
public class Item {
private int price;
private Function<Integer, Integer>[] itemExtras = new Function[]{};
public Item( int price ) {
this.price = price;
}
public Item( int price, Function<Integer, Integer>... itemExtras ) {
this.price = price;
this.itemExtras = itemExtras;
}
public int getPrice() {
Function<Integer, Integer> extras =
Stream.of( itemExtras )
.reduce( Function.identity(), Function::andThen );
return extras.apply( price );
}
public void setItemExtras( Function<Integer, Integer>... itemExtras ) {
this.itemExtras = itemExtras;
}
}
Recursões
Fibonacci
public static Long fib( int n ) {
if ( n < 2 ) {
return new Long( n );
} else {
return fib( n - 1 ) + fib( n - 2 );
}
}
Memoization
Pure Functions
In computer programming, a function may be described as a pure
function if both these statements about the function hold:
1-) The function always evaluates the same result value given
the same argument value(s). The function result value cannot
depend on any hidden information or state that may change as
program execution proceeds or between different executions of
the program, nor can it depend on any external input from I/O
devices (usually—see below.
2-) Evaluation of the result does not cause any semantically
observable side effect or output, such as mutation of mutable
objects or output to I/O devices (usually—see below)
Manual
Integer doubleValue(Integer x) {
return x * 2;
}
Integer doubleValue(Integer x) {
if (cache.containsKey(x)) {
return cache.get(x);
} else {
Integer result = x * 2;
cache.put(x, result) ;
return result;
}
}
private Map<Integer, Integer> cache = new ConcurrentHashMap<>();
public Integer fib(int n) {
if (n == 0 || n == 1) return n;
Integer result = cache.get( n );
if (result == null) {
synchronized (cache) {
result = cache.get(n);
if (result == null) {
result = fib(n - 2) + fib(n - 1);
cache.put(n, result);
}
}
}
return result;
}
Java + FP
to the rescue
private static Map<Integer, Long> memo = new HashMap<>();
static {
memo.put( 0, 0L ); //fibonacci(0)
memo.put( 1, 1L ); //fibonacci(1)
}
public static long fibonacci( int x ) {
return memo.
computeIfAbsent(
x, n -> fibonacci( n - 1 ) + fibonacci( n - 2 ) );
}
Currying
f(x,y) = y/x
f(2,3)
f(x,y) = y/x
f(2, y) = y / 2
g(y) = f(2,y) = y/2
g(y) = f(2,y) = y/2
g(3) = f(2,3) = 3/2
CtoF(x) = x * 9/5 + 32
static double converter( double x, double f, double b ) {
return x * f + b;
}
public static void main( String[] args ) {
Double celsius = 15.0;
Double fahrenheit = converter( celsius, 9.0 / 5, 32 ); //59 F
}
static double converter( double x, double f, double b ) {
return x * f + b;
}
static DoubleUnaryOperator curriedConverter( double f, double b ) {
return x -> x * f + b;
}
static DoubleUnaryOperator curriedConverter( double f, double b ) {
return x -> x * f + b;
}
public static void main( String[] args ) {
DoubleUnaryOperator convertCtoF = curriedConverter( 9.0 / 5, 32 );
convertCtoF.applyAsDouble( 35 ); //95 F
convertCtoF.applyAsDouble( 15 ); //59 F
}
static DoubleUnaryOperator curriedConverter( double f, double b ) {
return x -> x * f + b;
}
public static void main( String[] args ) {
DoubleUnaryOperator convertCtoF = curriedConverter( 9.0 / 5, 32 );
convertCtoF.applyAsDouble( 35 ); //95 F
DoubleUnaryOperator convertKmToMi = curriedConverter( 0.6214, 0 );
convertKmToMi.applyAsDouble( 804.672 ); //500milhas
}
DoubleUnaryOperator convertBRLtoUSD = curriedConverter( 0.27, 0 );
double usd = convertBRLtoUSD.applyAsDouble( 100 );//27 USD
DoubleUnaryOperator convertUSDtoEUR = curriedConverter( 0.89, 0 );
convertUSDtoEUR.applyAsDouble( usd ); //24.03 EUR
convertBRLtoUSD.andThen( convertUSDtoEUR ).applyAsDouble( 100 );
//24.03 EUR
E agora?
Programar funcional em Java é
uma mudança de paradigma
Java é multi-paradigma
Imperativo, OO e Funcional
Escolha o melhor deles para o
seu problema
Programação Funcional
trouxe uma nova vida
para o Java
DIVIRTA-SE!
Obrigado!!!
@ederign

Mais conteúdo relacionado

Mais procurados

mobl - model-driven engineering lecture
mobl - model-driven engineering lecturemobl - model-driven engineering lecture
mobl - model-driven engineering lecture
zefhemel
 
Data structures lab
Data structures labData structures lab
Data structures lab
Ragu Ram
 
関数潮流(Function Tendency)
関数潮流(Function Tendency)関数潮流(Function Tendency)
関数潮流(Function Tendency)
riue
 

Mais procurados (20)

Google Guava
Google GuavaGoogle Guava
Google Guava
 
mobl - model-driven engineering lecture
mobl - model-driven engineering lecturemobl - model-driven engineering lecture
mobl - model-driven engineering lecture
 
Scala 2 + 2 > 4
Scala 2 + 2 > 4Scala 2 + 2 > 4
Scala 2 + 2 > 4
 
Data structures lab
Data structures labData structures lab
Data structures lab
 
Fp java8
Fp java8Fp java8
Fp java8
 
Kotlin collections
Kotlin collectionsKotlin collections
Kotlin collections
 
Go ahead, make my day
Go ahead, make my dayGo ahead, make my day
Go ahead, make my day
 
Benefits of Kotlin
Benefits of KotlinBenefits of Kotlin
Benefits of Kotlin
 
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinAsync code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
 
Aggregation Pipeline Power++: MongoDB 4.2 파이프 라인 쿼리, 업데이트 및 구체화된 뷰 소개 [MongoDB]
Aggregation Pipeline Power++: MongoDB 4.2 파이프 라인 쿼리, 업데이트 및 구체화된 뷰 소개 [MongoDB]Aggregation Pipeline Power++: MongoDB 4.2 파이프 라인 쿼리, 업데이트 및 구체화된 뷰 소개 [MongoDB]
Aggregation Pipeline Power++: MongoDB 4.2 파이프 라인 쿼리, 업데이트 및 구체화된 뷰 소개 [MongoDB]
 
関数潮流(Function Tendency)
関数潮流(Function Tendency)関数潮流(Function Tendency)
関数潮流(Function Tendency)
 
Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015
 
Tuga it 2016 - What's New In C# 6
Tuga it 2016 - What's New In C# 6Tuga it 2016 - What's New In C# 6
Tuga it 2016 - What's New In C# 6
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript
 
Implementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 reduxImplementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 redux
 
はじめてのGroovy
はじめてのGroovyはじめてのGroovy
はじめてのGroovy
 
What's new in C# 6 - NetPonto Porto 20160116
What's new in C# 6  - NetPonto Porto 20160116What's new in C# 6  - NetPonto Porto 20160116
What's new in C# 6 - NetPonto Porto 20160116
 
Kotlin
KotlinKotlin
Kotlin
 
Groovy ネタ NGK 忘年会2009 ライトニングトーク
Groovy ネタ NGK 忘年会2009 ライトニングトークGroovy ネタ NGK 忘年会2009 ライトニングトーク
Groovy ネタ NGK 忘年会2009 ライトニングトーク
 
Hammurabi
HammurabiHammurabi
Hammurabi
 

Semelhante a TDC2016SP - Código funcional em Java: superando o hype

Please teach me how to fix the errors and where should be modified. .pdf
Please teach me how to fix the errors and where should be modified. .pdfPlease teach me how to fix the errors and where should be modified. .pdf
Please teach me how to fix the errors and where should be modified. .pdf
amarndsons
 
81818088 isc-class-xii-computer-science-project-java-programs
81818088 isc-class-xii-computer-science-project-java-programs81818088 isc-class-xii-computer-science-project-java-programs
81818088 isc-class-xii-computer-science-project-java-programs
Abhishek Jena
 

Semelhante a TDC2016SP - Código funcional em Java: superando o hype (20)

Sam wd programs
Sam wd programsSam wd programs
Sam wd programs
 
Lekcja stylu
Lekcja styluLekcja stylu
Lekcja stylu
 
Java 8 Puzzlers [as presented at OSCON 2016]
Java 8 Puzzlers [as presented at  OSCON 2016]Java 8 Puzzlers [as presented at  OSCON 2016]
Java 8 Puzzlers [as presented at OSCON 2016]
 
Java 8 new features or the ones you might actually use
Java 8 new features or the ones you might actually useJava 8 new features or the ones you might actually use
Java 8 new features or the ones you might actually use
 
Blocks+gcd入門
Blocks+gcd入門Blocks+gcd入門
Blocks+gcd入門
 
Oop lecture9 13
Oop lecture9 13Oop lecture9 13
Oop lecture9 13
 
Please teach me how to fix the errors and where should be modified. .pdf
Please teach me how to fix the errors and where should be modified. .pdfPlease teach me how to fix the errors and where should be modified. .pdf
Please teach me how to fix the errors and where should be modified. .pdf
 
AJUG April 2011 Cascading example
AJUG April 2011 Cascading exampleAJUG April 2011 Cascading example
AJUG April 2011 Cascading example
 
Groovy kind of test
Groovy kind of testGroovy kind of test
Groovy kind of test
 
Groovy kind of test
Groovy kind of testGroovy kind of test
Groovy kind of test
 
JAVA 8 : Migration et enjeux stratégiques en entreprise
JAVA 8 : Migration et enjeux stratégiques en entrepriseJAVA 8 : Migration et enjeux stratégiques en entreprise
JAVA 8 : Migration et enjeux stratégiques en entreprise
 
6. Generics. Collections. Streams
6. Generics. Collections. Streams6. Generics. Collections. Streams
6. Generics. Collections. Streams
 
C++ programs
C++ programsC++ programs
C++ programs
 
81818088 isc-class-xii-computer-science-project-java-programs
81818088 isc-class-xii-computer-science-project-java-programs81818088 isc-class-xii-computer-science-project-java-programs
81818088 isc-class-xii-computer-science-project-java-programs
 
Awt
AwtAwt
Awt
 
Embracing the-power-of-refactor
Embracing the-power-of-refactorEmbracing the-power-of-refactor
Embracing the-power-of-refactor
 
Mixing functional programming approaches in an object oriented language
Mixing functional programming approaches in an object oriented languageMixing functional programming approaches in an object oriented language
Mixing functional programming approaches in an object oriented language
 
Poly-paradigm Java
Poly-paradigm JavaPoly-paradigm Java
Poly-paradigm Java
 
Java Class Design
Java Class DesignJava Class Design
Java Class Design
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
 

Mais de tdc-globalcode

Mais de tdc-globalcode (20)

TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidadeTDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
 
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
 
TDC2019 Intel Software Day - ACATE - Cases de Sucesso
TDC2019 Intel Software Day - ACATE - Cases de SucessoTDC2019 Intel Software Day - ACATE - Cases de Sucesso
TDC2019 Intel Software Day - ACATE - Cases de Sucesso
 
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPATDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
 
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVinoTDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
 
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
 
TDC2019 Intel Software Day - Inferencia de IA em edge devices
TDC2019 Intel Software Day - Inferencia de IA em edge devicesTDC2019 Intel Software Day - Inferencia de IA em edge devices
TDC2019 Intel Software Day - Inferencia de IA em edge devices
 
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca PublicaTrilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
 
Trilha .Net - Programacao funcional usando f#
Trilha .Net - Programacao funcional usando f#Trilha .Net - Programacao funcional usando f#
Trilha .Net - Programacao funcional usando f#
 
TDC2018SP | Trilha Go - Case Easylocus
TDC2018SP | Trilha Go - Case EasylocusTDC2018SP | Trilha Go - Case Easylocus
TDC2018SP | Trilha Go - Case Easylocus
 
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
 
TDC2018SP | Trilha Go - Clean architecture em Golang
TDC2018SP | Trilha Go - Clean architecture em GolangTDC2018SP | Trilha Go - Clean architecture em Golang
TDC2018SP | Trilha Go - Clean architecture em Golang
 
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QATDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
 
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendenciaTDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
 
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR ServiceTDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
 
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NETTDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
 
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
 
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
 
TDC2018SP | Trilha .Net - .NET funcional com F#
TDC2018SP | Trilha .Net - .NET funcional com F#TDC2018SP | Trilha .Net - .NET funcional com F#
TDC2018SP | Trilha .Net - .NET funcional com F#
 
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor em .Net Core
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor  em .Net CoreTDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor  em .Net Core
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor em .Net Core
 

Último

Activity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdfActivity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdf
ciinovamais
 
Seal of Good Local Governance (SGLG) 2024Final.pptx
Seal of Good Local Governance (SGLG) 2024Final.pptxSeal of Good Local Governance (SGLG) 2024Final.pptx
Seal of Good Local Governance (SGLG) 2024Final.pptx
negromaestrong
 

Último (20)

Making communications land - Are they received and understood as intended? we...
Making communications land - Are they received and understood as intended? we...Making communications land - Are they received and understood as intended? we...
Making communications land - Are they received and understood as intended? we...
 
How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17
 
Asian American Pacific Islander Month DDSD 2024.pptx
Asian American Pacific Islander Month DDSD 2024.pptxAsian American Pacific Islander Month DDSD 2024.pptx
Asian American Pacific Islander Month DDSD 2024.pptx
 
Holdier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdfHoldier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdf
 
Key note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdfKey note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdf
 
Activity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdfActivity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdf
 
Sociology 101 Demonstration of Learning Exhibit
Sociology 101 Demonstration of Learning ExhibitSociology 101 Demonstration of Learning Exhibit
Sociology 101 Demonstration of Learning Exhibit
 
PROCESS RECORDING FORMAT.docx
PROCESS      RECORDING        FORMAT.docxPROCESS      RECORDING        FORMAT.docx
PROCESS RECORDING FORMAT.docx
 
psychiatric nursing HISTORY COLLECTION .docx
psychiatric  nursing HISTORY  COLLECTION  .docxpsychiatric  nursing HISTORY  COLLECTION  .docx
psychiatric nursing HISTORY COLLECTION .docx
 
General Principles of Intellectual Property: Concepts of Intellectual Proper...
General Principles of Intellectual Property: Concepts of Intellectual  Proper...General Principles of Intellectual Property: Concepts of Intellectual  Proper...
General Principles of Intellectual Property: Concepts of Intellectual Proper...
 
How to Manage Global Discount in Odoo 17 POS
How to Manage Global Discount in Odoo 17 POSHow to Manage Global Discount in Odoo 17 POS
How to Manage Global Discount in Odoo 17 POS
 
Introduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The BasicsIntroduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The Basics
 
This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.
 
Magic bus Group work1and 2 (Team 3).pptx
Magic bus Group work1and 2 (Team 3).pptxMagic bus Group work1and 2 (Team 3).pptx
Magic bus Group work1and 2 (Team 3).pptx
 
Accessible Digital Futures project (20/03/2024)
Accessible Digital Futures project (20/03/2024)Accessible Digital Futures project (20/03/2024)
Accessible Digital Futures project (20/03/2024)
 
Micro-Scholarship, What it is, How can it help me.pdf
Micro-Scholarship, What it is, How can it help me.pdfMicro-Scholarship, What it is, How can it help me.pdf
Micro-Scholarship, What it is, How can it help me.pdf
 
SOC 101 Demonstration of Learning Presentation
SOC 101 Demonstration of Learning PresentationSOC 101 Demonstration of Learning Presentation
SOC 101 Demonstration of Learning Presentation
 
Seal of Good Local Governance (SGLG) 2024Final.pptx
Seal of Good Local Governance (SGLG) 2024Final.pptxSeal of Good Local Governance (SGLG) 2024Final.pptx
Seal of Good Local Governance (SGLG) 2024Final.pptx
 
SKILL OF INTRODUCING THE LESSON MICRO SKILLS.pptx
SKILL OF INTRODUCING THE LESSON MICRO SKILLS.pptxSKILL OF INTRODUCING THE LESSON MICRO SKILLS.pptx
SKILL OF INTRODUCING THE LESSON MICRO SKILLS.pptx
 
Mixin Classes in Odoo 17 How to Extend Models Using Mixin Classes
Mixin Classes in Odoo 17  How to Extend Models Using Mixin ClassesMixin Classes in Odoo 17  How to Extend Models Using Mixin Classes
Mixin Classes in Odoo 17 How to Extend Models Using Mixin Classes
 

TDC2016SP - Código funcional em Java: superando o hype

  • 1. Código funcional em Java: Superando o hype Eder Ignatowicz Sr. Software Engineer JBoss by Red Hat
  • 5. public Pug( String nome, String color, Integer size ) { this.nome = nome; this.color = color; this.weight = size; } Pug dora = new Pug( "Dora", "abricot", 10 ); Pug bento = new Pug( "Bento", "abricot", 13 ); Pug jesse = new Pug( "Jesse", "black", 9 );
  • 6. Requisito: Filtrar todos os pugs de cor “abricot" da lista
  • 7. Filtrar todos os pugs de cor “abricot" da lista private static List<Pug> filterAbricotPugs( List<Pug> pugs ) { List<Pug> abricots = new ArrayList<>(); for ( Pug pug : pugs ) { if ( pug.getColor().equals( "abricot" ) ) { abricots.add( pug ); } } return abricots; } List<Pug> pugs = Arrays.asList( dora, bento, jesse ); List<Pug> abricot = filterAbricotPugs( pugs ); Pug{nome='Dora', color='abricot', weight=10} Pug{nome='Bento', color='abricot', weight=13}
  • 8. Novo Requisito: :) Filtrar todos os pugs de cor “black" da lista
  • 9. private static List<Pug> filterAbricotPugs( List<Pug> pugs ) { List<Pug> abricots = new ArrayList<>(); for ( Pug pug : pugs ) { if ( pug.getColor().equals( "abricot" ) ) { abricots.add( pug ); } } return abricots; } private static List<Pug> filterBlackPugs( List<Pug> pugs ) { List<Pug> abricots = new ArrayList<>(); for ( Pug pug : pugs ) { if ( pug.getColor().equals( "black" ) ) { abricots.add( pug ); } } return abricots; }
  • 10. Filtrar todos os pugs de cor “black" da lista private static List<Pug> filterPugByColor( List<Pug> pugs, String color ) { List<Pug> coloured = new ArrayList<>(); for ( Pug pug : pugs ) { if ( pug.getColor().equals( color ) ) { coloured.add( pug ); } } return coloured; } List<Pug> black = filterPugByColor( pugs, "black" ); black.forEach( System.out::println ); Pug{nome='Jesse', color='black', weight=9}
  • 11. Novo Requisito: :) Filtrar todos os pugs com sobrepeso (>10 kg)
  • 12. Filtrar todos os pugs com sobrepeso (>10 kg) private static List<Pug> filterPugBySize( List<Pug> pugs, int size ) { List<Pug> fat = new ArrayList<>(); for ( Pug pug : pugs ) { if ( pug.getWeight() > size ) { fat.add( pug ); } } return fat; } List<Pug> fat = filterPugBySize( pugs, 10 ); fat.forEach( System.out::println ); Pug{nome='Bento', color='abricot', weight=13}
  • 13. private static List<Pug> filterPugs( List<Pug> pugs, String color, int weight, boolean flag ) { List<Pug> result = new ArrayList<>(); for ( Pug pug : pugs ) { if ( ( flag && pug.getColor().equals( color ) ) || ( !flag && pug.getWeight() > weight ) ) { result.add( pug ); } } return result; } Refatorador :D
  • 14. List<Pug> result = filterPugs(pugs, "black", 0, true); List<Pug> result1 = filterPugs(pugs, "", 10, false);
  • 16. Behavior Parametrization public interface PugPredicate { boolean test(Pug pug); } class BlackPugPredicate implements PugPredicate{ @Override public boolean test( Pug pug ) { return pug.getColor().equals( "black" ); } } class FatPugPredicate implements PugPredicate{ @Override public boolean test( Pug pug ) { return pug.getWeight()>10; } }
  • 17. Predicate List<Pug> black = filterPug( pugs, new BlackPugPredicate() ); List<Pug> fat = filterPug( pugs, new FatPugPredicate() ); fat.forEach( System.out::println ); Pug{nome='Bento', color='abricot', weight=13}
  • 19. List<Pug> abricotsNotFat = filterPug( pugs, new PugPredicate() { @Override public boolean test( Pug pug ) { return pug.getColor().equals( "abricot" ) && pug.getWeight() <= 10; } } ); abricotsNotFat.forEach( System.out::println ); Pug{nome='Dora', color='abricot', weight=10}
  • 21. (Pug p1,Pug p2) -> p1.getWeight().compareTo(p2.getWeight()) Parâmetros do Lambda "Arrow" Corpo do Lambda
  • 22. class BlackPugPredicate implements PugPredicate{ @Override public boolean test( Pug pug ) { return "black".equals( pug.getColor() ) ); } } blacks = filterPug( pugs, new BlackPugPredicate() ); blacks = filterPug( pugs, (Pug pug) ->"black".equals( pug.getColor() ) );
  • 24. public interface Predicate<T>{ boolean test(T t); } public static <T> List<T> filter (List<T> list, Predicate<T> p){ List<T> result = new ArrayList<>();
 for(T e: list){ if(p.test(e)){ result.add(e); } } return result; }
  • 25. List<Pug> blacks = filter( pugs, (Pug pug) ->"black".equals( pug.getColor() ) ); List<Integer> pares = filter(numbers, i -> i % 2 == 0); Predicate<Pug> fatPredicate = d -> d.getWeight() > 9; Predicate<Pug> abricotPredicate1 = d -> d.getColor().equalsIgnoreCase( "abricot" ); Predicate<Pug> abricotAndFat = abricotPredicate.and( fatPredicate );
  • 26. @FunctionalInterface public interface Predicate<T>{ boolean test(T t); } public static <T> List<T> filter(List<T> list, Predicate<T> p) { List<T> results = new ArrayList<>(); for(T s: list){ if(p.test(s)){ results.add(s); } } return results; } Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty(); List<String> nonEmpty = filter(listOfStrings, nonEmptyStringPredicate); Predicate
  • 28. public class ShoppingCartTest { ShoppingCart cart; @Before public void setup() { Item item1 = new Item( 10 ); Item item2 = new Item( 20 ); cart = new ShoppingCart( Arrays.asList( item1, item2 ) ); } @Test public void totalTest() { cart.pay( ShoppingCart.PaymentMethod.CREDIT ) ); } }
  • 29. public class ShoppingCart { private List<Item> items; public ShoppingCart( List<Item> items ) { this.items = items; } public void pay( PaymentMethod method ) { int total = cartTotal(); if ( method == PaymentMethod.CREDIT ) { System.out.println( “Pay with credit “ + total ); } else if ( method == PaymentMethod.MONEY ) { System.out.println( “Pay with money “ + total ); } } private int cartTotal() { return items .stream() .mapToInt( Item::getValue ) .sum(); } … }
  • 30. public interface Payment { public void pay(int amount); } public class CreditCard implements Payment { @Override public void pay( int amount ) { System.out.println( "Pay with Credit: “+ amount); } } public class Money implements Payment { @Override public void pay( int amount ) { System.out.println( "Pay with Money: “+ amount); }
  • 31. public class ShoppingCart { … public void pay( Payment method ) { int total = cartTotal(); method.pay( total ); } private int cartTotal() { return items .stream() .mapToInt( Item::getValue ) .sum(); } }
  • 32. Strategy“Definir uma família de algoritmos, encapsular cada uma delas e torná-las intercambiáveis. Strategy permite que o algoritmo varie independentemente dos clientes que o utilizam” GAMMA, Erich et al.
  • 33. public interface Payment { public void pay(int amount); } public class CreditCard implements Payment { @Override public void pay( int amount ) { System.out.println( "make credit payment logic" ); } } public class Money implements Payment { @Override public void pay( int amount ) { System.out.println( "make money payment logic" ); } } public class DebitCard implements Payment { @Override public void pay( int amount ) { System.out.println( "make debit } } public void totalTest() { assertEquals( 30, cart.pay( new CreditCard() ) ); assertEquals( 30, cart.pay( new Money() ) ); assertEquals( 30, cart.pay( new DebitCard() ) ); } }
  • 34.
  • 35. public class ShoppingCart { … public void pay( Consumer<Integer> method ) { int total = cartTotal(); method.accept( total ); } … } public void pay( Payment method ) { int total = cartTotal(); method.pay( total ); }
  • 36. public class ShoppingCart { … public void pay( Consumer<Integer> method ) { int total = cartTotal(); method.accept( total ); } … } public void totalTest() { cart.pay( amount -> System.out.println( "Pay with Credit: " + amount ) ); cart.pay( amount -> System.out.println( "Pay with Money: " + amount ) ); cart.pay( amount -> System.out.println( "Pay with Debit: " + amount ) ); }
  • 37. public class PaymentTypes { public static void money( int amount ) { System.out.println( "Pay with Money: " + amount ); } public static void debit( int amount ) { System.out.println( "Pay with Debit: " + amount ); } public static void credit( int amount ) { System.out.println( "Pay with Credit: " + amount ); } } public void totalTest() { cart.pay( PaymentTypes::credit ); cart.pay( PaymentTypes::debit ); cart.pay( PaymentTypes::money ); }
  • 38. public class ShoppingCart { … public void pay( Consumer<Integer> method ) { int total = cartTotal(); method.accept( total ); } … } Strategy
  • 39.
  • 41.
  • 42. List<Pug> pugs = Arrays.asList( dora, bento, jesse ); Function<Pug, String> extractName = pug -> pug.getName(); List<String> nomes = pugs.stream() .map( extractName ) .collect( Collectors.toList() ); print( nomes ); Dora Bento Jesse
  • 43. List<Pug> pugs = Arrays.asList( dora, bento, jesse ); Function<Pug, String> extractName = pug -> pug.getName(); List<String> nomes = pugs.stream() .map( extractName ) .collect( Collectors.toList() ); print( nomes ); UnaryOperator<String> upper = s -> s.toUpperCase();
  • 44. List<Pug> pugs = Arrays.asList( dora, bento, jesse ); Function<Pug, String> extractName = pug -> pug.getName(); List<String> nomes = pugs.stream() .map( extractName ) .collect( Collectors.toList() ); print( nomes ); UnaryOperator<String> upper = s -> s.toUpperCase(); List<String> nomesUpper = pugs.stream() .map( extractName.andThen( upper ) ) .collect( Collectors.toList() ); print( nomesUpper );
  • 45. public class Item { private int price; public Item( int price ) { this.price = price; } public int getPrice() { return price; } } Extras Envio Impostos Embalagem
  • 46. public interface Item { int getPrice(); } public class Book implements Item { private int price; public Book( int price ) { this.price = price; } @Override public int getPrice() { return price; } }
  • 47. public abstract class ItemExtras implements Item { private Item item; public ItemExtras( Item item ) { this.item = item; } @Override public int getPrice() { return item.getPrice(); } }
  • 48. public class InternationalDelivery extends ItemExtras { public InternationalDelivery( Item item ) { super( item ); } @Override public int getPrice() { return 5 + super.getPrice(); } }
  • 49. public class GiftPacking extends ItemExtras { public GiftPacking( Item item ) { super( item ); } @Override public int getPrice() { return 15 + super.getPrice(); } }
  • 50. public static void main( String[] args ) { Item book = new Book( 10 ); book.getPrice(); //10 Item international = new InternationalDelivery( book ); international.getPrice(); //15 }
  • 51. public static void main( String[] args ) { Item book = new Book( 10 ); book.getPrice(); //10 Item internationalGift = new GiftPacking( new InternationalDelivery( book ) ); internationalGift.getPrice(); //30 }
  • 52. public static void main( String[] args ) { Item book = new Book( 10 ); book.getPrice(); //10 Item internationalGiftWithTaxes = new InternacionalTaxes( new GiftPacking( new InternationalDelivery( book ); internationalGiftWithTaxes.getPrice(); //80 } }
  • 53. Decorator“Dinamicamente, agregar responsabilidades adicionais a objetos. Os Decorators fornecem uma alternativa flexível ao uso de subclasses para extensão de funcionalidades.” GAMMA, Erich et al.
  • 55. public static void main( String[] args ) { Item book = new Item( 10 ); book.getPrice(); //10 Function<Integer, Integer> giftPacking = value -> value + 15; giftPacking.apply( book.getPrice() ); //25 }
  • 56. public static void main( String[] args ) { Item book = new Item( 10 ); book.getPrice(); //10 Function<Integer, Integer> giftPacking = value -> value + 15; giftPacking.apply( book.getPrice() ); //25 Function<Integer, Integer> intTaxes = value -> value + 50; intTaxes.apply( book.getPrice() ); //60 }
  • 57. public static void main( String[] args ) { Item book = new Item( 10 ); book.getPrice(); //10 Function<Integer, Integer> giftPacking = value -> value + 15; giftPacking.apply( book.getPrice() ); //25 Function<Integer, Integer> intTaxes = value -> value + 50; intTaxes.apply( book.getPrice() ); //60 giftPacking.andThen( intTaxes ).apply( book.getPrice() ); //75 }
  • 58. public class Item { private int price; private Function<Integer, Integer>[] itemExtras = new Function[]{}; public Item( int price ) { this.price = price; } public Item( int price, Function<Integer, Integer>... itemExtras) { this.price = price; this.itemExtras = itemExtras; } public int getPrice() { int priceWithExtras = price; for ( Function<Integer, Integer> itemExtra : itemExtras ) { priceWithExtras = itemExtra.apply( priceWithExtras ); } return priceWithExtras; } public void setItemExtras( Function<Integer, Integer>... itemExtras ) { this.itemExtras = itemExtras; } }
  • 59. public static void main( String[] args ) { Item book = new Item( 10 ); Function<Integer, Integer> giftPacking = value -> value + 15; Function<Integer, Integer> intTaxes = value -> value + 50; book.setItemExtras( giftPacking, intTaxes ); book.getPrice(); //75 }
  • 60. public static void main( String[] args ) { Item book = new Item( 10 ); Function<Integer, Integer> giftPacking = value -> value + 15; Function<Integer, Integer> intTaxes = value -> value + 50; book.setItemExtras( giftPacking, intTaxes ); book.getPrice(); //75 }
  • 61. public class Packing { public static Integer giftPacking( Integer value ) { return value + 15; } //other packing options here } public class Taxes { public static Integer internacional( Integer value ) { return value + 50; } //other taxes here }
  • 62. public static void main( String[] args ) { Item book = new Item( 10, Packing::giftPacking, Taxes::internacional ); book.getPrice(); //75 }
  • 63. public class Item { private int price; private Function<Integer, Integer>[] itemExtras = new Function[]{}; public Item( int price ) { this.price = price; } public Item( int price, Function<Integer, Integer>... itemExtras) { this.price = price; this.itemExtras = itemExtras; } public int getPrice() { int priceWithExtras = price; for ( Function<Integer, Integer> itemExtra : itemExtras ) { priceWithExtras = itemExtra.apply( priceWithExtras ); } return priceWithExtras; } public void setItemExtras( Function<Integer, Integer>... itemExtras ) { this.itemExtras = itemExtras; } }
  • 64. public class Item { private int price; private Function<Integer, Integer>[] itemExtras = new Function[]{}; public Item( int price ) { this.price = price; } public Item( int price, Function<Integer, Integer>... itemExtras ) { this.price = price; this.itemExtras = itemExtras; } public int getPrice() { Function<Integer, Integer> extras = Stream.of( itemExtras ) .reduce( Function.identity(), Function::andThen ); return extras.apply( price ); } public void setItemExtras( Function<Integer, Integer>... itemExtras ) { this.itemExtras = itemExtras; } }
  • 67. public static Long fib( int n ) { if ( n < 2 ) { return new Long( n ); } else { return fib( n - 1 ) + fib( n - 2 ); } }
  • 68.
  • 69.
  • 71. Pure Functions In computer programming, a function may be described as a pure function if both these statements about the function hold: 1-) The function always evaluates the same result value given the same argument value(s). The function result value cannot depend on any hidden information or state that may change as program execution proceeds or between different executions of the program, nor can it depend on any external input from I/O devices (usually—see below. 2-) Evaluation of the result does not cause any semantically observable side effect or output, such as mutation of mutable objects or output to I/O devices (usually—see below)
  • 73. Integer doubleValue(Integer x) { return x * 2; } Integer doubleValue(Integer x) { if (cache.containsKey(x)) { return cache.get(x); } else { Integer result = x * 2; cache.put(x, result) ; return result; } }
  • 74. private Map<Integer, Integer> cache = new ConcurrentHashMap<>(); public Integer fib(int n) { if (n == 0 || n == 1) return n; Integer result = cache.get( n ); if (result == null) { synchronized (cache) { result = cache.get(n); if (result == null) { result = fib(n - 2) + fib(n - 1); cache.put(n, result); } } } return result; }
  • 75. Java + FP to the rescue
  • 76. private static Map<Integer, Long> memo = new HashMap<>(); static { memo.put( 0, 0L ); //fibonacci(0) memo.put( 1, 1L ); //fibonacci(1) } public static long fibonacci( int x ) { return memo. computeIfAbsent( x, n -> fibonacci( n - 1 ) + fibonacci( n - 2 ) ); }
  • 77.
  • 81. f(2, y) = y / 2 g(y) = f(2,y) = y/2
  • 82. g(y) = f(2,y) = y/2 g(3) = f(2,3) = 3/2
  • 83. CtoF(x) = x * 9/5 + 32
  • 84. static double converter( double x, double f, double b ) { return x * f + b; } public static void main( String[] args ) { Double celsius = 15.0; Double fahrenheit = converter( celsius, 9.0 / 5, 32 ); //59 F }
  • 85. static double converter( double x, double f, double b ) { return x * f + b; } static DoubleUnaryOperator curriedConverter( double f, double b ) { return x -> x * f + b; }
  • 86. static DoubleUnaryOperator curriedConverter( double f, double b ) { return x -> x * f + b; } public static void main( String[] args ) { DoubleUnaryOperator convertCtoF = curriedConverter( 9.0 / 5, 32 ); convertCtoF.applyAsDouble( 35 ); //95 F convertCtoF.applyAsDouble( 15 ); //59 F }
  • 87. static DoubleUnaryOperator curriedConverter( double f, double b ) { return x -> x * f + b; } public static void main( String[] args ) { DoubleUnaryOperator convertCtoF = curriedConverter( 9.0 / 5, 32 ); convertCtoF.applyAsDouble( 35 ); //95 F DoubleUnaryOperator convertKmToMi = curriedConverter( 0.6214, 0 ); convertKmToMi.applyAsDouble( 804.672 ); //500milhas }
  • 88. DoubleUnaryOperator convertBRLtoUSD = curriedConverter( 0.27, 0 ); double usd = convertBRLtoUSD.applyAsDouble( 100 );//27 USD DoubleUnaryOperator convertUSDtoEUR = curriedConverter( 0.89, 0 ); convertUSDtoEUR.applyAsDouble( usd ); //24.03 EUR convertBRLtoUSD.andThen( convertUSDtoEUR ).applyAsDouble( 100 ); //24.03 EUR
  • 90. Programar funcional em Java é uma mudança de paradigma
  • 92. Escolha o melhor deles para o seu problema
  • 93. Programação Funcional trouxe uma nova vida para o Java