SlideShare a Scribd company logo
The… Wonderful? World of
Lambdas
David Gómez
@dgomezg
Esther Lozano
@esloho
Parameterized
behaviour
It’s cool!!
More concise
code
Become a
Functional
Programmer in Java
Packing the backpack
A real chat
Just saw a simple and
useful case for lambdas:
better logging!
A real chat
Just saw a simple and
useful case for lambdas:
better logging!
A new Object
instance for each log
statement… isn’t it a
bit overkill?
Not sugar syntax
public class SimpleInnerClassUse {
public void executeAction(Action action) {
action.execute();
}
public static void main (String ... args) {
new SimpleInnerClassUse().executeAction(new Action() {
@Override
public void execute() {
System.out.println("Action Executed (Inner class)");
}
});
}
}
Not sugar syntax
public static void main (String ... args) {
new SimpleInnerClassUse().executeAction(new Action() {
@Override
public void execute() {
System.out.println("Action Executed (Inner class)");
}public static void main(java.lang.String...);
flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS
Code:
stack=3, locals=1, args_size=1
0: new #3 // class com/autentia/training/java8/lambdas/SimpleInnerClassUse
3: dup
4: invokespecial #4 // Method "<init>":()V
7: new #5 // class com/autentia/training/java8/lambdas/SimpleInnerClassUse$1
10: dup
11: invokespecial #6 // Method
com/autentia/training/java8/lambdas/SimpleInnerClassUse$1."<init>":()V
14: invokevirtual #7 // Method
executeAction:(Lcom/autentia/training/java8/functionalinterfaces/Action;)V
17: return
Not sugar syntax
public class SimpleLambdaUse {
public void executeAction(Action action) {
action.execute();
}
public static void main (String ... args) {
new SimpleLambdaUse().executeAction(
()-> System.out.println("action executed!"));
}
}
Not sugar syntax
public static void main (String ... args) {
new SimpleLambdaUse().executeAction(
()-> System.out.println("action executed!"));
}
public static void main(java.lang.String...);
flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS
Code:
stack=2, locals=1, args_size=1
0: new #3 // class
com/autentia/training/java8/lambdas/SimpleLambdaUse
3: dup
4: invokespecial #4 // Method "<init>":()V
7: invokedynamic #5, 0 // InvokeDynamic
#0:execute:()Lcom/autentia/training/java8/functionalinterfaces/Action;
12: invokevirtual #6 // Method
executeAction:(Lcom/autentia/training/java8/functionalinterfaces/Action;)V
15: return
Not sugar syntax
Less impact in ClassLoader, Memory & GC
$ ls -la com/autentia/training/java8/lambdas/*.class
com/autentia/training/java8/lambdas/SimpleInnerClassUse$1.class
com/autentia/training/java8/lambdas/SimpleInnerClassUse.class
com/autentia/training/java8/lambdas/SimpleLambdaUse.class
Not so new: SAM Types & @FunctionalInterface
Have you ever used…?
public interface Runnable {
public abstract void run();
}
Not so new: SAM Types & @FunctionalInterface
Have you ever used…?
public interface Runnable {
public abstract void run();
}
Single Abstract Method (SAM type)
Not so new: SAM Types & @FunctionalInterface
Have you ever used…?
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
Single Abstract Method (SAM type)
Functional Interface
From imperative to declarative
Imperative code:
List<Integer> numbers = //List of random numbers
List<Integer> evenNumbers = new ArrayList<>();
for (int i : numbers) {
if (i % 2 == 0) {
evenNumbers.add(i);
}
}
From imperative to declarative
Declarative code:
List<Integer> numbers = //List of random numbers
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(toList());
From imperative to declarative
More concise:
phoneCallLog.stream()
.filter(phoneCall ->
phoneCall.getTime().getMonth() == Month.JUNE)
.map(phoneCall -> phoneCall.getContact().getName())
.distinct()
.forEach(System.out::println);
Lambdas & its context
public class SimpleInnerClassUse {
public static void main (String ... args) {
new SimpleInnerClassUse().executeAction(new Action() {
public String whoAmI() {
return this.getClass().getName();
}
@Override
public void execute() {
System.out.println("I am " + this.whoAmI());
}
});
}
}
Lambdas & its context
public class SimpleInnerClassUse {
public static void main (String ... args) {
new SimpleInnerClassUse().executeAction(new Action() {
public String whoAmI() {
return this.getClass().getName();
}
@Override
public void execute() {
System.out.println("I am " + this.whoAmI());
}
});
}
}
Lambdas & its context
public class SimpleInnerClassUse {
public static void main (String ... args) {
new SimpleInnerClassUse().executeAction(new Action() {
public String whoAmI() {
return this.getClass().getName();
}
@Override
public void execute() {
System.out.println("I am " + this.whoAmI());
}
});
}
}
I am com.autentia.training.java8.lambdas.SimpleInnerClassUse$1
Lambdas & its context
public class SimpleLambdaUse {
public static void main (String ... args) {
new SimpleLambdaUse().invokeFromInstance();
}
public void invokeFromInstance() {
executeAction(() -> System.out.println("I am " + this.whoAmI()));
}
public String whoAmI() {
return SimpleLambdaUse.class.getSimpleName();
}
}
public class SimpleLambdaUse {
public static void main (String ... args) {
new SimpleLambdaUse().invokeFromInstance();
}
public void invokeFromInstance() {
executeAction(() -> System.out.println("I am " + this.whoAmI()));
}
public String whoAmI() {
return this.getClass().getSimpleName();
}
}
Lambdas & its context
public class SimpleLambdaUse {
public static void main (String ... args) {
new SimpleLambdaUse().invokeFromInstance();
}
public void invokeFromInstance() {
executeAction(() -> System.out.println("I am " + this.whoAmI()));
}
public String whoAmI() {
return this.getClass().getSimpleName();
}
}
Lambdas & its context: this & super
I am SimpleLambdaUse
Lambdas & its context
● Variable capture? Use variable inherited from context?
○ Stateless lambdas
()->System.out.println("Doing Stuff...")
○ Capturing lambdas
() -> System.out.println(seeds[Math.round(Math.random()*10)])
Hit the road!
The slopes of anonymous inner classes
● First use case: lambdas as replacement for anonymous inner classes
ExecutorService threadPool = Executors.newCachedThreadPool();
threadPool.submit(
new Runnable() {
@Override
public void run() {
System.out.println("doing stuff...");
}
}
);
() -> void
The slopes of anonymous inner classes
● First use case: lambdas as replacement for anonymous inner classes
ExecutorService threadPool = Executors.newCachedThreadPool();
threadPool.submit(()->System.out.println("Doing Stuff..."));
() -> void
The fields of java.util.function
Do you remember?
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
The fields of java.util.function
The fields of java.util.function
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
Function<RowSet, Contact> contactJdbcMapper = row -> {
Contact c = new Contact();
c.setName(row.getString(0));
...
return c;
}
The fields of java.util.function
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
Function<RowSet, Contact> contactJdbcMapper = row -> new Contact(row);
The fields of java.util.function
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
Function<RowSet, Contact> contactJdbcMapper = Contact::new;
The meadows of method parameters
● Parameterized behaviour → lazy usage → logging crazy example
public void log(Level level, String msg) {
if (!isLoggable(level)) {
return;
}
LogRecord lr = new LogRecord(level, msg);
doLog(lr);
}
Logger log = Logger.getLogger(LoggingCrazy.class.getSimpleName());
log.log(Level.FINE, heavyObject.expensiveToStringConversion());
The meadows of method parameters
● Parameterized behaviour → lazy usage → logging crazy example
public void log(Level level, Supplier<String> msgSupplier) {
if (!isLoggable(level)) {
return;
}
LogRecord lr = new LogRecord(level, msgSupplier.get());
doLog(lr);
}
Logger log = Logger.getLogger(LoggingCrazy.class.getSimpleName());
log.log(Level.FINE, () -> heavyObject.expensiveToStringConversion()
The meadows of method parameters
● Parameterized behaviour → lazy usage → logging crazy example
log.log(Level.FINE, heavyObject.expensiveToStringConversion());
log.log(Level.FINE, () -> heavyObject.expensiveToStringConversion());
time logging 100_000_000 times without supplier 10689 ms
time logging 100_000_000 times with supplier 102 ms
The loch of function composition
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
The loch of function composition
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
}
The loch of function composition
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
}
The loch of function composition
new OrderPriceCalculator()
.andThen( Taxes::generalTax )
.andThen( Carrier::shippingCost )
.andThen( Customer::profileDiscount )
.apply( order );
The cliffs of Function Return
You can return functions instead of values (lazy evaluation of return values)
public BiFunction<Integer, Integer, Integer> lazyMultiplier(int val1, int val2) {
return (x,y) -> val1*val2;
}
Now you feel like a cool FP
Abusing lambdas
Abusing lambdas: Breaking effectively final rule
public class CapturingLambdas {
private int[] seeds = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
private int[] calculatedValue = new int[1];
public void calculate() {
ExecutorService threadPool = Executors.newFixedThreadPool(2);
threadPool.execute(() -> calculatedValue[0] = seeds[Math.round(Math.random()*10));
}
}
Performance un-improvement
throw new RuntimeException(
"Two or more components with same type."
+ " Please use @Named to select one. Candidates: "
+ candidateNames.toString() );
Performance un-improvement
throw new RuntimeException(
"Two or more components with same type."
+ " Please use @Named to select one. Candidates: "
+ candidateNames.toString() );
java.lang.RuntimeException: Two or more components with the
same type. Please use @Named to select one. Candidates:
[Ljava.lang.String;@65f1fa47
Performance un-improvement
throw new RuntimeException(
"Two or more components with same type."
+ " Please use @Named to select one. Candidates: "
+ Arrays.asList(candidateNames)
.stream().collect(joining(",", "[", "]")));
Performance un-improvement
throw new RuntimeException(
"Two or more components with same type."
+ " Please use @Named to select one. Candidates: "
+ Arrays.asList(candidateNames)
.stream().collect(joining(",", "[", "]")));
java.lang.RuntimeException: Two or more components with the
same type. Please use @Named to select one. Candidates:
[Component1, Component2, Component3]
Performance un-improvement
Arrays.asList(candidateNames)
.stream().collect(joining(",", "[", "]")));
87 ms
(1000 iter)
StringBuilder sb = new StringBuilder( "[");
for (String candidate : candidates) {
if (sb.length()> 1) {
sb.append( ",");
}
sb.append(candidate);
}
Return sb.append("]").toString();
4 ms
(1000 iter)
Optionals
return Optional
.ofNullable(eventConsumers.get(eventType))
.orElseThrow(() ->
new EventConsumerNotFoundException(
"Consumer for event type '" + channel
+ "' has not been found."));
Lambdas gone wild
@Override
public String deserializeResult(Parser parser) {
Node root = new ObjectMapper().read(parser);
if (root.size() > 0) {
Node result = root.get(0).get("result");
if (result != null) {
return result.asText();
} else {
return null;
}
} else {
return null;
}
}
Lambdas gone wild
@Override
public String deserializeMessage(Parser parser) {
Node root = new ObjectMapper().read(parser);
if (root.size() > 0) {
return Optional.ofNullable(root.get(0).get("result"))
.map(result -> result.asText())
.orElse(null);
} else {
return null;
}
}
Lambdas gone wild
@Override
public String deserializeMessage(Parser parser) {
Node root = new ObjectMapper().read(parser);
if (root.size() > 0) {
return Optional.ofNullable(root.get(0).get("result"))
.map(Node::asText)
.orElse(null);
} else {
return null;
}
}
Lambdas gone wild
Can we get rid of that extra check?
public String deserializeMessage(Parser parser) {
Node root = new ObjectMapper().read(parser);
return Stream.of(Optional.ofNullable(root.get(0)))
.filter(Optional::isPresent)
.map(Optional::get)
.map(resultNode -> Optional.ofNullable(resultNode.get("result")))
.filter(Optional::isPresent)
.map(JsonNode::asText)
.findFirst()
.orElse(null);
}
Lambdas gone wild
public String deserializeMessage(Parser parser) {
return Stream.of(Optional.ofNullable(new ObjectMapper().read(parser).get(0)))
.filter(Optional::isPresent)
.map(Optional::get)
.map(resultNode -> Optional.ofNullable(resultNode.get("result")))
.filter(Optional::isPresent)
.map(JsonNode::asText)
.findFirst()
.orElse(null);
}
Lambdas gone wild
After peer review, we decided to get back to:
@Override
public String deserializeMessage(Parser parser) {
Node root = new ObjectMapper().read(parser);
if (root.size() > 0) {
return Optional.ofNullable(root.get(0).get("result"))
.map(Node::asText)
.orElse(null);
} else {
return null;
}
}
Although we could have tried to split the lambda in several methods.
Playing with FP concepts
We start with a simple adder function
private BiFunction<Integer, Integer, Integer> adder = (x, y) -> x+y;
We need several other incrementers by a fixed value
private Function<Integer, Integer> incrementByOne = x -> x+1;
private Function<Integer, Integer> incrementByTwo = x -> x+2;
private Function<Integer, Integer> incrementByThree = x -> x+3;
Playing with FP concepts
We start with a simple adder function
private BiFunction<Integer, Integer, Integer> adder = (x, y) -> x+y;
We need several other incrementers by a fixed value
private Function<Integer, Integer> incrementByOne = x -> x+1;
private Function<Integer, Integer> incrementByTwo = x -> x+2;
private Function<Integer, Integer> incrementByThree = x -> x+3;
Playing with FP concepts
Maybe I can abstract this a little bit:
//Curryfying the increment Function
private Function<Integer, Function<Integer,Integer>> incrementBy = y -> x -> x+y;
So, I can rewrite the incrementers:
private Function<Integer, Integer> incrementByOne = x -> incrementBy.apply(1).apply(x);
private Function<Integer, Integer> incrementByTwo = x -> incrementBy.apply(2).apply(x);
private Function<Integer, Integer> incrementByThree = x -> incrementBy.apply(3).apply(x);
Playing with FP concepts
Wait, I can abstract (again) the incrementBy:
private Function<Integer, Integer> incrementByOne = x -> incrementBy.apply(1).apply(x);
private Function<Integer, Integer> incrementByTwo = x -> incrementBy.apply(2).apply(x);
private Function<Integer, Integer> incrementByThree =
x -> incrementBy.apply(3).apply(x);
…..
private BiFunction<Integer, Integer, Integer> sum =
(x,y) -> incrementBy.apply(x).apply(y);
Which is the base:
private BiFunction<Integer, Integer, Integer> sum = (x,y) -> x+y;
Playing with FP concepts
From
private Function<Integer, Integer> incrementByOne = x -> incrementBy.apply(1).apply(x);
Can be simplified as (there is a redundant function)
private Function<Integer, Integer> incrementByOne = x -> incrementBy.apply(1);
private Function<Integer, Integer> incrementByTwo = x -> incrementBy.apply(2);
private Function<Integer, Integer> incrementByThree = x -> incrementBy.apply(3);
Conclusions
● Simplicity vs performance
● Don’t over use: Conciseness means short and readable! Not only short
● Step back and ask a colleague to read and understand your code
Ready to take the road to
the world of lambdas?
Better take the road to http://Lambda.World
David Gómez
@dgomezg
Esther Lozano
@esloho
The… Wonderful? World of
Lambdas

More Related Content

What's hot

Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Mario Fusco
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondMario Fusco
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMMario Fusco
 
Kotlin, why?
Kotlin, why?Kotlin, why?
Kotlin, why?
Paweł Byszewski
 
Java 8 Lambda Built-in Functional Interfaces
Java 8 Lambda Built-in Functional InterfacesJava 8 Lambda Built-in Functional Interfaces
Java 8 Lambda Built-in Functional Interfaces
Ganesh Samarthyam
 
Java 8 Streams
Java 8 StreamsJava 8 Streams
Java 8 Streams
Manvendra Singh
 
Comparing JVM languages
Comparing JVM languagesComparing JVM languages
Comparing JVM languages
Jose Manuel Ortega Candel
 
Functional Programming in Java 8 - Exploiting Lambdas
Functional Programming in Java 8 - Exploiting LambdasFunctional Programming in Java 8 - Exploiting Lambdas
Functional Programming in Java 8 - Exploiting Lambdas
Ganesh Samarthyam
 
Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8
RichardWarburton
 
OOP and FP - Become a Better Programmer
OOP and FP - Become a Better ProgrammerOOP and FP - Become a Better Programmer
OOP and FP - Become a Better Programmer
Mario Fusco
 
Refactoring to Java 8 (Devoxx BE)
Refactoring to Java 8 (Devoxx BE)Refactoring to Java 8 (Devoxx BE)
Refactoring to Java 8 (Devoxx BE)
Trisha Gee
 
Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...
Mario Fusco
 
Java gets a closure
Java gets a closureJava gets a closure
Java gets a closure
Tomasz Kowalczewski
 
Functional Java 8 in everyday life
Functional Java 8 in everyday lifeFunctional Java 8 in everyday life
Functional Java 8 in everyday life
Andrea Iacono
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
Mario Fusco
 
Parallel streams in java 8
Parallel streams in java 8Parallel streams in java 8
Parallel streams in java 8
David Gómez García
 
Advanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesAdvanced Debugging Using Java Bytecodes
Advanced Debugging Using Java Bytecodes
Ganesh Samarthyam
 
Nice to meet Kotlin
Nice to meet KotlinNice to meet Kotlin
Nice to meet Kotlin
Jieyi Wu
 
The Ring programming language version 1.8 book - Part 37 of 202
The Ring programming language version 1.8 book - Part 37 of 202The Ring programming language version 1.8 book - Part 37 of 202
The Ring programming language version 1.8 book - Part 37 of 202
Mahmoud Samir Fayed
 
Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1
José Paumard
 

What's hot (20)

Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
 
Kotlin, why?
Kotlin, why?Kotlin, why?
Kotlin, why?
 
Java 8 Lambda Built-in Functional Interfaces
Java 8 Lambda Built-in Functional InterfacesJava 8 Lambda Built-in Functional Interfaces
Java 8 Lambda Built-in Functional Interfaces
 
Java 8 Streams
Java 8 StreamsJava 8 Streams
Java 8 Streams
 
Comparing JVM languages
Comparing JVM languagesComparing JVM languages
Comparing JVM languages
 
Functional Programming in Java 8 - Exploiting Lambdas
Functional Programming in Java 8 - Exploiting LambdasFunctional Programming in Java 8 - Exploiting Lambdas
Functional Programming in Java 8 - Exploiting Lambdas
 
Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8
 
OOP and FP - Become a Better Programmer
OOP and FP - Become a Better ProgrammerOOP and FP - Become a Better Programmer
OOP and FP - Become a Better Programmer
 
Refactoring to Java 8 (Devoxx BE)
Refactoring to Java 8 (Devoxx BE)Refactoring to Java 8 (Devoxx BE)
Refactoring to Java 8 (Devoxx BE)
 
Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...
 
Java gets a closure
Java gets a closureJava gets a closure
Java gets a closure
 
Functional Java 8 in everyday life
Functional Java 8 in everyday lifeFunctional Java 8 in everyday life
Functional Java 8 in everyday life
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
Parallel streams in java 8
Parallel streams in java 8Parallel streams in java 8
Parallel streams in java 8
 
Advanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesAdvanced Debugging Using Java Bytecodes
Advanced Debugging Using Java Bytecodes
 
Nice to meet Kotlin
Nice to meet KotlinNice to meet Kotlin
Nice to meet Kotlin
 
The Ring programming language version 1.8 book - Part 37 of 202
The Ring programming language version 1.8 book - Part 37 of 202The Ring programming language version 1.8 book - Part 37 of 202
The Ring programming language version 1.8 book - Part 37 of 202
 
Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1
 

Similar to The... Wonderful? World of Lambdas

JavaOne 2016 - Learn Lambda and functional programming
JavaOne 2016 - Learn Lambda and functional programmingJavaOne 2016 - Learn Lambda and functional programming
JavaOne 2016 - Learn Lambda and functional programming
Henri Tremblay
 
Wien15 java8
Wien15 java8Wien15 java8
Wien15 java8
Jaanus Pöial
 
Lambda Functions in Java 8
Lambda Functions in Java 8Lambda Functions in Java 8
Lambda Functions in Java 8
Ganesh Samarthyam
 
New Functional Features of Java 8
New Functional Features of Java 8New Functional Features of Java 8
New Functional Features of Java 8
franciscoortin
 
Major Java 8 features
Major Java 8 featuresMajor Java 8 features
Major Java 8 features
Sanjoy Kumar Roy
 
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
Akaks
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In Java
Andrei Solntsev
 
Productive Programming in Java 8 - with Lambdas and Streams
Productive Programming in Java 8 - with Lambdas and Streams Productive Programming in Java 8 - with Lambdas and Streams
Productive Programming in Java 8 - with Lambdas and Streams
Ganesh Samarthyam
 
Rx workshop
Rx workshopRx workshop
Rx workshop
Ryan Riley
 
Hierarchical free monads and software design in fp
Hierarchical free monads and software design in fpHierarchical free monads and software design in fp
Hierarchical free monads and software design in fp
Alexander Granin
 
Java 8 new features
Java 8 new featuresJava 8 new features
Java 8 new features
Aniket Thakur
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
JAXLondon_Conference
 
Java SE 8
Java SE 8Java SE 8
Functional programming in javascript
Functional programming in javascriptFunctional programming in javascript
Functional programming in javascript
Boris Burdiliak
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming ii
Prashant Kalkar
 
Java 8 presentation
Java 8 presentationJava 8 presentation
Java 8 presentation
Van Huong
 
Java 8 features
Java 8 featuresJava 8 features
Java 8 features
NexThoughts Technologies
 
Java 8
Java 8Java 8
Java 8
vilniusjug
 
Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0
Sheik Uduman Ali
 

Similar to The... Wonderful? World of Lambdas (20)

Functional Programming
Functional ProgrammingFunctional Programming
Functional Programming
 
JavaOne 2016 - Learn Lambda and functional programming
JavaOne 2016 - Learn Lambda and functional programmingJavaOne 2016 - Learn Lambda and functional programming
JavaOne 2016 - Learn Lambda and functional programming
 
Wien15 java8
Wien15 java8Wien15 java8
Wien15 java8
 
Lambda Functions in Java 8
Lambda Functions in Java 8Lambda Functions in Java 8
Lambda Functions in Java 8
 
New Functional Features of Java 8
New Functional Features of Java 8New Functional Features of Java 8
New Functional Features of Java 8
 
Major Java 8 features
Major Java 8 featuresMajor Java 8 features
Major Java 8 features
 
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In Java
 
Productive Programming in Java 8 - with Lambdas and Streams
Productive Programming in Java 8 - with Lambdas and Streams Productive Programming in Java 8 - with Lambdas and Streams
Productive Programming in Java 8 - with Lambdas and Streams
 
Rx workshop
Rx workshopRx workshop
Rx workshop
 
Hierarchical free monads and software design in fp
Hierarchical free monads and software design in fpHierarchical free monads and software design in fp
Hierarchical free monads and software design in fp
 
Java 8 new features
Java 8 new featuresJava 8 new features
Java 8 new features
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
 
Java SE 8
Java SE 8Java SE 8
Java SE 8
 
Functional programming in javascript
Functional programming in javascriptFunctional programming in javascript
Functional programming in javascript
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming ii
 
Java 8 presentation
Java 8 presentationJava 8 presentation
Java 8 presentation
 
Java 8 features
Java 8 featuresJava 8 features
Java 8 features
 
Java 8
Java 8Java 8
Java 8
 
Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0
 

More from Esther Lozano

Aterrizando en JS: Consejos para [node]sesperar en el intento
Aterrizando en JS: Consejos para [node]sesperar en el intentoAterrizando en JS: Consejos para [node]sesperar en el intento
Aterrizando en JS: Consejos para [node]sesperar en el intento
Esther Lozano
 
Aterrizando en JS: consejos para [node]sesperar en el intento
Aterrizando en JS: consejos para [node]sesperar en el intentoAterrizando en JS: consejos para [node]sesperar en el intento
Aterrizando en JS: consejos para [node]sesperar en el intento
Esther Lozano
 
Una Javera en JS: consejos para [node]sesperar en el intento
Una Javera en JS: consejos para [node]sesperar en el intentoUna Javera en JS: consejos para [node]sesperar en el intento
Una Javera en JS: consejos para [node]sesperar en el intento
Esther Lozano
 
Ansible party in the [Google] clouds
Ansible party in the [Google] cloudsAnsible party in the [Google] clouds
Ansible party in the [Google] clouds
Esther Lozano
 
Geb+spock: let your functional tests live long and prosper
Geb+spock: let your functional tests live long and prosperGeb+spock: let your functional tests live long and prosper
Geb+spock: let your functional tests live long and prosper
Esther Lozano
 
Geb+spock: larga y próspera vida a tus tests funcionales
Geb+spock: larga y próspera vida a tus tests funcionalesGeb+spock: larga y próspera vida a tus tests funcionales
Geb+spock: larga y próspera vida a tus tests funcionales
Esther Lozano
 

More from Esther Lozano (6)

Aterrizando en JS: Consejos para [node]sesperar en el intento
Aterrizando en JS: Consejos para [node]sesperar en el intentoAterrizando en JS: Consejos para [node]sesperar en el intento
Aterrizando en JS: Consejos para [node]sesperar en el intento
 
Aterrizando en JS: consejos para [node]sesperar en el intento
Aterrizando en JS: consejos para [node]sesperar en el intentoAterrizando en JS: consejos para [node]sesperar en el intento
Aterrizando en JS: consejos para [node]sesperar en el intento
 
Una Javera en JS: consejos para [node]sesperar en el intento
Una Javera en JS: consejos para [node]sesperar en el intentoUna Javera en JS: consejos para [node]sesperar en el intento
Una Javera en JS: consejos para [node]sesperar en el intento
 
Ansible party in the [Google] clouds
Ansible party in the [Google] cloudsAnsible party in the [Google] clouds
Ansible party in the [Google] clouds
 
Geb+spock: let your functional tests live long and prosper
Geb+spock: let your functional tests live long and prosperGeb+spock: let your functional tests live long and prosper
Geb+spock: let your functional tests live long and prosper
 
Geb+spock: larga y próspera vida a tus tests funcionales
Geb+spock: larga y próspera vida a tus tests funcionalesGeb+spock: larga y próspera vida a tus tests funcionales
Geb+spock: larga y próspera vida a tus tests funcionales
 

Recently uploaded

Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Anthony Dahanne
 
Enhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdfEnhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdf
Globus
 
Designing for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesDesigning for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web Services
KrzysztofKkol1
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
takuyayamamoto1800
 
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
XfilesPro
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
Tier1 app
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
vrstrong314
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
Globus
 
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Globus
 
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke
 
Explore Modern SharePoint Templates for 2024
Explore Modern SharePoint Templates for 2024Explore Modern SharePoint Templates for 2024
Explore Modern SharePoint Templates for 2024
Sharepoint Designs
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Shahin Sheidaei
 
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Globus
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
Ortus Solutions, Corp
 
Why React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdfWhy React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdf
ayushiqss
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
Globus
 
Strategies for Successful Data Migration Tools.pptx
Strategies for Successful Data Migration Tools.pptxStrategies for Successful Data Migration Tools.pptx
Strategies for Successful Data Migration Tools.pptx
varshanayak241
 

Recently uploaded (20)

Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
 
Enhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdfEnhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdf
 
Designing for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesDesigning for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web Services
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
 
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
 
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...
 
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBroker
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
Explore Modern SharePoint Templates for 2024
Explore Modern SharePoint Templates for 2024Explore Modern SharePoint Templates for 2024
Explore Modern SharePoint Templates for 2024
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
 
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
 
Why React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdfWhy React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdf
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
 
Strategies for Successful Data Migration Tools.pptx
Strategies for Successful Data Migration Tools.pptxStrategies for Successful Data Migration Tools.pptx
Strategies for Successful Data Migration Tools.pptx
 

The... Wonderful? World of Lambdas

  • 1. The… Wonderful? World of Lambdas David Gómez @dgomezg Esther Lozano @esloho
  • 4. A real chat Just saw a simple and useful case for lambdas: better logging!
  • 5. A real chat Just saw a simple and useful case for lambdas: better logging! A new Object instance for each log statement… isn’t it a bit overkill?
  • 6. Not sugar syntax public class SimpleInnerClassUse { public void executeAction(Action action) { action.execute(); } public static void main (String ... args) { new SimpleInnerClassUse().executeAction(new Action() { @Override public void execute() { System.out.println("Action Executed (Inner class)"); } }); } }
  • 7. Not sugar syntax public static void main (String ... args) { new SimpleInnerClassUse().executeAction(new Action() { @Override public void execute() { System.out.println("Action Executed (Inner class)"); }public static void main(java.lang.String...); flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS Code: stack=3, locals=1, args_size=1 0: new #3 // class com/autentia/training/java8/lambdas/SimpleInnerClassUse 3: dup 4: invokespecial #4 // Method "<init>":()V 7: new #5 // class com/autentia/training/java8/lambdas/SimpleInnerClassUse$1 10: dup 11: invokespecial #6 // Method com/autentia/training/java8/lambdas/SimpleInnerClassUse$1."<init>":()V 14: invokevirtual #7 // Method executeAction:(Lcom/autentia/training/java8/functionalinterfaces/Action;)V 17: return
  • 8. Not sugar syntax public class SimpleLambdaUse { public void executeAction(Action action) { action.execute(); } public static void main (String ... args) { new SimpleLambdaUse().executeAction( ()-> System.out.println("action executed!")); } }
  • 9. Not sugar syntax public static void main (String ... args) { new SimpleLambdaUse().executeAction( ()-> System.out.println("action executed!")); } public static void main(java.lang.String...); flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS Code: stack=2, locals=1, args_size=1 0: new #3 // class com/autentia/training/java8/lambdas/SimpleLambdaUse 3: dup 4: invokespecial #4 // Method "<init>":()V 7: invokedynamic #5, 0 // InvokeDynamic #0:execute:()Lcom/autentia/training/java8/functionalinterfaces/Action; 12: invokevirtual #6 // Method executeAction:(Lcom/autentia/training/java8/functionalinterfaces/Action;)V 15: return
  • 10. Not sugar syntax Less impact in ClassLoader, Memory & GC $ ls -la com/autentia/training/java8/lambdas/*.class com/autentia/training/java8/lambdas/SimpleInnerClassUse$1.class com/autentia/training/java8/lambdas/SimpleInnerClassUse.class com/autentia/training/java8/lambdas/SimpleLambdaUse.class
  • 11. Not so new: SAM Types & @FunctionalInterface Have you ever used…? public interface Runnable { public abstract void run(); }
  • 12. Not so new: SAM Types & @FunctionalInterface Have you ever used…? public interface Runnable { public abstract void run(); } Single Abstract Method (SAM type)
  • 13. Not so new: SAM Types & @FunctionalInterface Have you ever used…? @FunctionalInterface public interface Runnable { public abstract void run(); } Single Abstract Method (SAM type) Functional Interface
  • 14. From imperative to declarative Imperative code: List<Integer> numbers = //List of random numbers List<Integer> evenNumbers = new ArrayList<>(); for (int i : numbers) { if (i % 2 == 0) { evenNumbers.add(i); } }
  • 15. From imperative to declarative Declarative code: List<Integer> numbers = //List of random numbers List<Integer> evenNumbers = numbers.stream() .filter(n -> n % 2 == 0) .collect(toList());
  • 16. From imperative to declarative More concise: phoneCallLog.stream() .filter(phoneCall -> phoneCall.getTime().getMonth() == Month.JUNE) .map(phoneCall -> phoneCall.getContact().getName()) .distinct() .forEach(System.out::println);
  • 17. Lambdas & its context public class SimpleInnerClassUse { public static void main (String ... args) { new SimpleInnerClassUse().executeAction(new Action() { public String whoAmI() { return this.getClass().getName(); } @Override public void execute() { System.out.println("I am " + this.whoAmI()); } }); } }
  • 18. Lambdas & its context public class SimpleInnerClassUse { public static void main (String ... args) { new SimpleInnerClassUse().executeAction(new Action() { public String whoAmI() { return this.getClass().getName(); } @Override public void execute() { System.out.println("I am " + this.whoAmI()); } }); } }
  • 19. Lambdas & its context public class SimpleInnerClassUse { public static void main (String ... args) { new SimpleInnerClassUse().executeAction(new Action() { public String whoAmI() { return this.getClass().getName(); } @Override public void execute() { System.out.println("I am " + this.whoAmI()); } }); } } I am com.autentia.training.java8.lambdas.SimpleInnerClassUse$1
  • 20. Lambdas & its context public class SimpleLambdaUse { public static void main (String ... args) { new SimpleLambdaUse().invokeFromInstance(); } public void invokeFromInstance() { executeAction(() -> System.out.println("I am " + this.whoAmI())); } public String whoAmI() { return SimpleLambdaUse.class.getSimpleName(); } }
  • 21. public class SimpleLambdaUse { public static void main (String ... args) { new SimpleLambdaUse().invokeFromInstance(); } public void invokeFromInstance() { executeAction(() -> System.out.println("I am " + this.whoAmI())); } public String whoAmI() { return this.getClass().getSimpleName(); } } Lambdas & its context
  • 22. public class SimpleLambdaUse { public static void main (String ... args) { new SimpleLambdaUse().invokeFromInstance(); } public void invokeFromInstance() { executeAction(() -> System.out.println("I am " + this.whoAmI())); } public String whoAmI() { return this.getClass().getSimpleName(); } } Lambdas & its context: this & super I am SimpleLambdaUse
  • 23. Lambdas & its context ● Variable capture? Use variable inherited from context? ○ Stateless lambdas ()->System.out.println("Doing Stuff...") ○ Capturing lambdas () -> System.out.println(seeds[Math.round(Math.random()*10)])
  • 25. The slopes of anonymous inner classes ● First use case: lambdas as replacement for anonymous inner classes ExecutorService threadPool = Executors.newCachedThreadPool(); threadPool.submit( new Runnable() { @Override public void run() { System.out.println("doing stuff..."); } } ); () -> void
  • 26. The slopes of anonymous inner classes ● First use case: lambdas as replacement for anonymous inner classes ExecutorService threadPool = Executors.newCachedThreadPool(); threadPool.submit(()->System.out.println("Doing Stuff...")); () -> void
  • 27. The fields of java.util.function Do you remember? @FunctionalInterface public interface Runnable { public abstract void run(); }
  • 28. The fields of java.util.function
  • 29. The fields of java.util.function @FunctionalInterface public interface Function<T, R> { R apply(T t); } Function<RowSet, Contact> contactJdbcMapper = row -> { Contact c = new Contact(); c.setName(row.getString(0)); ... return c; }
  • 30. The fields of java.util.function @FunctionalInterface public interface Function<T, R> { R apply(T t); } Function<RowSet, Contact> contactJdbcMapper = row -> new Contact(row);
  • 31. The fields of java.util.function @FunctionalInterface public interface Function<T, R> { R apply(T t); } Function<RowSet, Contact> contactJdbcMapper = Contact::new;
  • 32. The meadows of method parameters ● Parameterized behaviour → lazy usage → logging crazy example public void log(Level level, String msg) { if (!isLoggable(level)) { return; } LogRecord lr = new LogRecord(level, msg); doLog(lr); } Logger log = Logger.getLogger(LoggingCrazy.class.getSimpleName()); log.log(Level.FINE, heavyObject.expensiveToStringConversion());
  • 33. The meadows of method parameters ● Parameterized behaviour → lazy usage → logging crazy example public void log(Level level, Supplier<String> msgSupplier) { if (!isLoggable(level)) { return; } LogRecord lr = new LogRecord(level, msgSupplier.get()); doLog(lr); } Logger log = Logger.getLogger(LoggingCrazy.class.getSimpleName()); log.log(Level.FINE, () -> heavyObject.expensiveToStringConversion()
  • 34. The meadows of method parameters ● Parameterized behaviour → lazy usage → logging crazy example log.log(Level.FINE, heavyObject.expensiveToStringConversion()); log.log(Level.FINE, () -> heavyObject.expensiveToStringConversion()); time logging 100_000_000 times without supplier 10689 ms time logging 100_000_000 times with supplier 102 ms
  • 35. The loch of function composition @FunctionalInterface public interface Function<T, R> { R apply(T t); }
  • 36. The loch of function composition @FunctionalInterface public interface Function<T, R> { R apply(T t); default <V> Function<V, R> compose(Function<? super V, ? extends T> before) { Objects.requireNonNull(before); return (V v) -> apply(before.apply(v)); } }
  • 37. The loch of function composition @FunctionalInterface public interface Function<T, R> { R apply(T t); default <V> Function<V, R> compose(Function<? super V, ? extends T> before) { Objects.requireNonNull(before); return (V v) -> apply(before.apply(v)); } default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); } }
  • 38. The loch of function composition new OrderPriceCalculator() .andThen( Taxes::generalTax ) .andThen( Carrier::shippingCost ) .andThen( Customer::profileDiscount ) .apply( order );
  • 39. The cliffs of Function Return You can return functions instead of values (lazy evaluation of return values) public BiFunction<Integer, Integer, Integer> lazyMultiplier(int val1, int val2) { return (x,y) -> val1*val2; }
  • 40. Now you feel like a cool FP
  • 42. Abusing lambdas: Breaking effectively final rule public class CapturingLambdas { private int[] seeds = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; private int[] calculatedValue = new int[1]; public void calculate() { ExecutorService threadPool = Executors.newFixedThreadPool(2); threadPool.execute(() -> calculatedValue[0] = seeds[Math.round(Math.random()*10)); } }
  • 43. Performance un-improvement throw new RuntimeException( "Two or more components with same type." + " Please use @Named to select one. Candidates: " + candidateNames.toString() );
  • 44. Performance un-improvement throw new RuntimeException( "Two or more components with same type." + " Please use @Named to select one. Candidates: " + candidateNames.toString() ); java.lang.RuntimeException: Two or more components with the same type. Please use @Named to select one. Candidates: [Ljava.lang.String;@65f1fa47
  • 45. Performance un-improvement throw new RuntimeException( "Two or more components with same type." + " Please use @Named to select one. Candidates: " + Arrays.asList(candidateNames) .stream().collect(joining(",", "[", "]")));
  • 46. Performance un-improvement throw new RuntimeException( "Two or more components with same type." + " Please use @Named to select one. Candidates: " + Arrays.asList(candidateNames) .stream().collect(joining(",", "[", "]"))); java.lang.RuntimeException: Two or more components with the same type. Please use @Named to select one. Candidates: [Component1, Component2, Component3]
  • 47. Performance un-improvement Arrays.asList(candidateNames) .stream().collect(joining(",", "[", "]"))); 87 ms (1000 iter) StringBuilder sb = new StringBuilder( "["); for (String candidate : candidates) { if (sb.length()> 1) { sb.append( ","); } sb.append(candidate); } Return sb.append("]").toString(); 4 ms (1000 iter)
  • 48. Optionals return Optional .ofNullable(eventConsumers.get(eventType)) .orElseThrow(() -> new EventConsumerNotFoundException( "Consumer for event type '" + channel + "' has not been found."));
  • 49. Lambdas gone wild @Override public String deserializeResult(Parser parser) { Node root = new ObjectMapper().read(parser); if (root.size() > 0) { Node result = root.get(0).get("result"); if (result != null) { return result.asText(); } else { return null; } } else { return null; } }
  • 50. Lambdas gone wild @Override public String deserializeMessage(Parser parser) { Node root = new ObjectMapper().read(parser); if (root.size() > 0) { return Optional.ofNullable(root.get(0).get("result")) .map(result -> result.asText()) .orElse(null); } else { return null; } }
  • 51. Lambdas gone wild @Override public String deserializeMessage(Parser parser) { Node root = new ObjectMapper().read(parser); if (root.size() > 0) { return Optional.ofNullable(root.get(0).get("result")) .map(Node::asText) .orElse(null); } else { return null; } }
  • 52. Lambdas gone wild Can we get rid of that extra check? public String deserializeMessage(Parser parser) { Node root = new ObjectMapper().read(parser); return Stream.of(Optional.ofNullable(root.get(0))) .filter(Optional::isPresent) .map(Optional::get) .map(resultNode -> Optional.ofNullable(resultNode.get("result"))) .filter(Optional::isPresent) .map(JsonNode::asText) .findFirst() .orElse(null); }
  • 53. Lambdas gone wild public String deserializeMessage(Parser parser) { return Stream.of(Optional.ofNullable(new ObjectMapper().read(parser).get(0))) .filter(Optional::isPresent) .map(Optional::get) .map(resultNode -> Optional.ofNullable(resultNode.get("result"))) .filter(Optional::isPresent) .map(JsonNode::asText) .findFirst() .orElse(null); }
  • 54. Lambdas gone wild After peer review, we decided to get back to: @Override public String deserializeMessage(Parser parser) { Node root = new ObjectMapper().read(parser); if (root.size() > 0) { return Optional.ofNullable(root.get(0).get("result")) .map(Node::asText) .orElse(null); } else { return null; } } Although we could have tried to split the lambda in several methods.
  • 55. Playing with FP concepts We start with a simple adder function private BiFunction<Integer, Integer, Integer> adder = (x, y) -> x+y; We need several other incrementers by a fixed value private Function<Integer, Integer> incrementByOne = x -> x+1; private Function<Integer, Integer> incrementByTwo = x -> x+2; private Function<Integer, Integer> incrementByThree = x -> x+3;
  • 56. Playing with FP concepts We start with a simple adder function private BiFunction<Integer, Integer, Integer> adder = (x, y) -> x+y; We need several other incrementers by a fixed value private Function<Integer, Integer> incrementByOne = x -> x+1; private Function<Integer, Integer> incrementByTwo = x -> x+2; private Function<Integer, Integer> incrementByThree = x -> x+3;
  • 57. Playing with FP concepts Maybe I can abstract this a little bit: //Curryfying the increment Function private Function<Integer, Function<Integer,Integer>> incrementBy = y -> x -> x+y; So, I can rewrite the incrementers: private Function<Integer, Integer> incrementByOne = x -> incrementBy.apply(1).apply(x); private Function<Integer, Integer> incrementByTwo = x -> incrementBy.apply(2).apply(x); private Function<Integer, Integer> incrementByThree = x -> incrementBy.apply(3).apply(x);
  • 58. Playing with FP concepts Wait, I can abstract (again) the incrementBy: private Function<Integer, Integer> incrementByOne = x -> incrementBy.apply(1).apply(x); private Function<Integer, Integer> incrementByTwo = x -> incrementBy.apply(2).apply(x); private Function<Integer, Integer> incrementByThree = x -> incrementBy.apply(3).apply(x); ….. private BiFunction<Integer, Integer, Integer> sum = (x,y) -> incrementBy.apply(x).apply(y); Which is the base: private BiFunction<Integer, Integer, Integer> sum = (x,y) -> x+y;
  • 59. Playing with FP concepts From private Function<Integer, Integer> incrementByOne = x -> incrementBy.apply(1).apply(x); Can be simplified as (there is a redundant function) private Function<Integer, Integer> incrementByOne = x -> incrementBy.apply(1); private Function<Integer, Integer> incrementByTwo = x -> incrementBy.apply(2); private Function<Integer, Integer> incrementByThree = x -> incrementBy.apply(3);
  • 60. Conclusions ● Simplicity vs performance ● Don’t over use: Conciseness means short and readable! Not only short ● Step back and ask a colleague to read and understand your code
  • 61. Ready to take the road to the world of lambdas?
  • 62. Better take the road to http://Lambda.World