SlideShare une entreprise Scribd logo
1  sur  10
Lambda Expressions in JAVA
Java is a first-class object-oriented language. With the exception of primitive
data types, everything in Java is an object. Even an array is an Object. Every class creates
instances that are objects. There is no way of defining just a function / method which stays in
Java all by itself. There is no way of passing a method as argument or returning a method
body for that instance.
Since the old days of Swing, we always had written anonymous classes if we wanted to pass
some functionality to any method. For example the old event listener code used to look like:
someObject.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
//Event listener implementation goes here...
}
});
Here we wanted to add some custom code to Mouse listener. We defined an anonymous inner
class MouseAdapter and created its object. This way we passed some functionality to
addMouseListener method.
In short, it is not easy to pass plain methods / functionalities in Java that can be passed as
arguments. Due to this limitation Java 8 adds a brand new language level feature
called Lambda Expressions. Lambda expressions are coming to Java 8 and together with
Raoul-Gabriel Urma and Alan Mycroft I .
External vs. internal iteration
Let's start with something very simple, a list of integers:
1.List<Integer> numbers = Arrays.list(1, 2, 3, 4, 5, 6);
and a for cycle that iterates all the items in the list and prints them:
1.for (int number : numbers) {
2.System.out.println(number);
3.}
Straightforward as much as common: I don't remember a single day when we haven't write at
least one cycle like this. For example ananya puts away her toys after having played with
them. It goes on more or less in this way:
Me: " ananya, let's put the toys away. Is there a toy on the ground"
ananya: "Yes, the ball"
Me: "Ok, put the ball in the box. Is there something else?"
ananya: "Yes, there is my doll"
Me: "Ok, put the doll in the box. Is there something else?"
ananya: "Yes, there is my book"
Me: "Ok, put the book in the box. Is there something else?"
ananya: "No, nothing else"
Me: "Fine, we are done"
This is exactly what we do everyday with our Java collections. We iterate the collection
externally, explicitly pulling out and processing the items one by one. It would be far better
for me if I could tell to ananya just: "put inside the box all the toys that are on the ground".
There are two other reasons, why an internal iteration is preferable: first ananya could choose
to take at the same time the doll with one hand and the ball with the other and second she
could decide to take the objects closest to the box first and then the others. In the same way
using an internal iteration the JIT compiler could optimize it processing the items in parallel
or in a different order. These optimizations are impossible if we iterate the collection
externally as we are used to do in Java and more in general with the imperative programming.
So, why don't we iterate internally? I think this is only a bad mental habit caused by the lack
of support of this pattern in the Java Collection Framework that in turn has been caused by
the verbosity (creation of an anonymous inner class) that this implies in pre-8 Java.
Something like this:
1.numbers.forEach(new Consumer<Integer>() {
2.public void accept(Integer value) {
3.System.out.println(value);
4.}
5.});
Structure of Lambda Expressions
Let’s check the structure of lambda expressions.
A lambda expression can have zero, one or more parameters.
The type of the parameters can be explicitly declared or it can be inferred from the context.
e.g. (int a) is same as just (a)
Parameters are enclosed in parentheses and separated by commas. e.g. (a, b) or (int a, int
b)or (String a, int b, float c)
Empty parentheses are used to represent an empty set of parameters. e.g. () -> 42
When there is a single parameter, if its type is inferred, it is not mandatory to use
parentheses. e.g. a -> return a*a
The body of the lambda expressions can contain zero, one or more statements.
If body of lambda expression has single statement curly brackets are not mandatory and
the return type of the anonymous function is the same as that of the body expression.
When there is more than one statement in body than these must be enclosed in curly
brackets (a code block) and the return type of the anonymous function is the same as the
type of the value returned within the code block, or void if nothing is returned.
What are Functional Interfaces?
In Java, a Marker interface is an interface with no methods or fields declaration. In simple
words, marker interface is an empty interface. Similarly, a Functional Interface is an interface
with just one abstract method declared in it.
java.lang.Runnable is an example of a Functional Interface. There is only one method void
run()declared in Runnable interface. Similarly ActionListener interface is also a Functional
Interface. We use Anonymous inner classes to instantiate objects of functional interface. With
Lambda expressions, this can be simplified.
Each lambda expression can be implicitly assigned to one of the interface called Functional
interface. For example we can create Runnable interface’s reference from lambda expression
like below:
Runnable r = () -> System.out.println("hello world");
This type of conversion is automatically taken care by compiler when we dont specify the
functional interface. For example:
new Thread(
() -> System.out.println("hello world")
).start();
So in above code, compiler automatically deduced that lambda expression can be casted to
Runnable interface from Thread class’s constructor signature public Thread(Runnable r) { }.
Few examples of lambda expressions and their functional interface:
Consumer<Integer> c = (int x) -> { System.out.println(x) };
BiConsumer<Integer, String> b = (Integer x, String y) -> System.out.println(x + " : " +
y);
Predicate<String> p = (String s) -> { s == null };
@FunctionalInterface is a new interface added in Java 8 to indicate that an interface type
declaration is intended to be a functional interface as defined by the Java Language
Specification. Java 8 also declared number of Functional Interfaces that can be used by
Lambda expressions. @FunctionalInterface can be used for compiler level errors when the
interface you have annotated is not a valid Functional Interface.
Following is an example of custom defined Functional interface.
@FunctionalInterface
public interface WorkerInterface {
public void doSomeWork();
}
As its definition says, Functional Interfaces can have only one abstract method. If you try to
add one more abstract method in it, it throws compile time error. For example:
@FunctionalInterface
public interface WorkerInterface {
public void doSomeWork();
public void doSomeMoreWork();
}
Error:
Unexpected @FunctionalInterface annotation
@FunctionalInterface ^ WorkerInterface is not a functional interface multiple
non-overriding abstract methods found in interface WorkerInterface 1 error
Once the Functional interface is defined, we can simply use it in our API and take advantage
of Lambda expressions. For example:
//define a functional interface
@FunctionalInterface
public interface WorkerInterface {
public void doSomeWork();
}
public class WorkerInterfaceTest {
public static void execute(WorkerInterface worker) {
worker.doSomeWork();
}
public static void main(String [] args) {
//invoke doSomeWork using Annonymous class
execute(new WorkerInterface() {
@Override
public void doSomeWork() {
System.out.println("Worker invoked using Anonymous class");
}
});
//invoke doSomeWork using Lambda expression
execute( () -> System.out.println("Worker invoked using Lambda expression") );
}
}
Output:
Worker invoked using Anonymous class
Worker invoked using Lambda expression
Here we created our own Functional interface and used to with lambda expressions. execute()
method can now take lambda expressions as argument.
In Java 8 lambda expressions allow to achieve the same result in a less verbose and more
readable way:
1.numbers.forEach((Integer value) -> System.out.println(value));
The lambda expression is made of two parts the one on the left of the arrow symbol (->)
listing its parameters and the one on the right containing its body. In this case the compiler
automatically figures out that the lambda expression has the same signature of the only non
implemented method of the Consumer interface (that for this reason is called a functional
interface) and treat the first as it was an instance of the second, even if the generated bytecode
could potentially be different. The declaration of the types of the lambda expression
arguments can be, in the biggest part of cases, inferred by the compiler and then omitted as it
follows:
1.numbers.forEach(value -> System.out.println(value));
But we can rewrite this last statement even more concisely using a method reference, another
feature introduced in Java 8. More in details in Java 8 it is possible to reference both a static
and an instance a method using the new :: operator as in:
1.numbers.forEach(System.out::println);
In this way, with a process that in functional programming is known as eta expansion, the
name of the method is "expanded" by the compiler in the method itself that, as we have
already seen, has the same signature of the only abstract method of the Consumer functional
interface and then can be in turn converted in an instance of it.
Lambda expression adds that missing link of functional programming to Java.
in Java, the lambda expressions are represented as objects, and so they must be bound to a
particular object type known as a functional interface.
Passing behaviors, not only values :-
What we have seen in the former example is the main and possibly the only reason why
lambda expressions are so useful. Passing a lambda expression to another function allow us
to pass not only values but also behaviors and this enable to dramatically raise the level of
our abstraction and then project more generic, flexible and reusable API. Let's reenforce this
with a further example: starting with the usual list of Integer
1.List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
we are requested to write a method that sums all the Integers in the list as for instance:
1.public int sumAll(List<Integer> numbers) {
2.int total = 0;
3.for (int number : numbers) {
4.total += number;
5.}
6.return total;
7.}
The day after a manager comes to our cubicle and tells you that the business also requires to
have a function that sums only the even number in the list. So what is the quickest thing we
could do? Easy. Just copy and paste the former method and add to it the required filtering
condition:
01.public int sumAllEven(List<Integer> numbers) {
02.int total = 0;
03.for (int number : numbers) {
04.if (number % 2 == 0) {
05.total += number;
06.}
07.}
08.return total;
09.}
Another day, another requirement: this time they need to sum the numbers in the list again
but only if they are greater than 3. So what could we do? Well, we could again copy and
paste the former method and just change that boolean condition ... but it feels so dirty, isn't it?
Now, following the "First Write, Second Copy, Third Refactor" principle it is time to wonder
if there is a smarter and more generic way to do this. In this case implementing an higher-
order function accepting together with the list also a Predicate (another functional interface
added in Java 8) that defines how to filter the numbers in the list itself before to sum them
up.
01.public int sumAll(List<Integer> numbers, Predicate<Integer> p) {
02.int total = 0;
03.for (int number : numbers) {
04.if (p.test(number)) {
05.total += number;
06.}
07.}
08.return total;
09.}
In other words we are passing to the method not only the data (the list of numbers) but also a
behavior (the Predicate) defining how to use them. In this way we can satisfy all the 3
requirements with a single more generic and then more reusable method:
1.sumAll(numbers, n -> true);
2.sumAll(numbers, n -> n % 2 == 0);
3.sumAll(numbers, n -> n > 3);
Examples of Lambda Expressions :
Thread can be initialized like following:
//Old way:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello from thread");
}
}).start();
//New way:
new Thread(
() -> System.out.println("Hello from thread")
).start();
The event handling can be done with Java 8 using lambda expression. Following code we
show both old and new way of adding ActionListener to a UI component.
//Old way:
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("The button was clicked using old fashion code!");
}
});
//New way:
button.addActionListener( (e) -> {
System.out.println("The button was clicked. From lambda expressions !");
});
Simple code to print all elements of given array. Note there is one more way of using lambda
expression. In below example we use the usual way of creating lambda expression using
arrow syntax and also we used a brand new double colon (::) operator that Java 8 has to
convert a normal method into lambda expression.
//Old way:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
for(Integer n: list) {
System.out.println(n);
}
//New way:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
list.forEach(n -> System.out.println(n));
//or we can use :: double colon operator in Java 8
list.forEach(System.out::println);
In this example we use Predicate functional interface to create a test and print the elements
that pass the test. This way you can provide the logic using lambda expression and do
something based on it.
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class Main {
public static void main(String [] a) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
System.out.println("Print all numbers:");
evaluate(list, (n)->true);
System.out.println("Print no numbers:");
evaluate(list, (n)->false);
System.out.println("Print even numbers:");
evaluate(list, (n)-> n%2 == 0 );
System.out.println("Print odd numbers:");
evaluate(list, (n)-> n%2 == 1 );
System.out.println("Print numbers greater than 5:");
evaluate(list, (n)-> n > 5 );
}
public static void evaluate(List<Integer> list, Predicate<Integer> predicate) {
for(Integer n: list) {
if(predicate.test(n)) {
System.out.println(n + " ");
}
}
}
}
Output:
Print all numbers: 1 2 3 4 5 6 7
Print no numbers:
Print even numbers: 2 4 6
Print odd numbers: 1 3 5 7
Print numbers greater than 5: 6 7
Some wizardry using Lambda expression to print square of each element of a list. Notice we
used .stream() method to convert regular list into a steam. Java 8 added some awesome
Stream APIs.java.util.stream.Stream interface comes with tons of useful methods which can
be used along with lambda expression to do some voodoo. We passed a lambda expression x
-> x*x to map() method which applies this to all elements of the stream. After that we use
forEach to print the all elements of list.
//Old way:
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
for(Integer n : list) {
int x = n * n;
System.out.println(x);
}
//New way:
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
list.stream().map((x) -> x*x).forEach(System.out::println);
Given a list, sum the square of each element from this list. See how Lambda expression can
be used to achieve this in a single statement. This is also a starters example on MapReduce.
We used map() to square each element and then reduce() to reduce all elements into single
number.
//Old way:
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
int sum = 0;
for(Integer n : list) {
int x = n * n;
sum = sum + x;
}
System.out.println(sum);
//New way:
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
int sum = list.stream().map(x -> x*x).reduce((x,y) -> x + y).get();
System.out.println(sum);
Difference between Lambda Expression and Anonymous class:
One key difference between using Anonymous class and Lambda expression is
the use of this keyword. For anonymous class ‘this’ keyword resolves to anonymous class,
whereas for lambda expression ‘this’ keyword resolves to enclosing class where lambda is
written.
Another difference between lambda expression and anonymous class is in the way these two
are compiled. Java compiler compiles lambda expressions and convert them into private
method of the class. It uses invokedynamic instruction that was added in Java 7 to bind this
method dynamically.

Contenu connexe

Dernier

Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 

Dernier (20)

Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 

En vedette

Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsPixeldarts
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthThinkNow
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfmarketingartwork
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Applitools
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at WorkGetSmarter
 

En vedette (20)

Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage Engineerings
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work
 

Easiest way to understand Lambda expressions in java 1.8

  • 1. Lambda Expressions in JAVA Java is a first-class object-oriented language. With the exception of primitive data types, everything in Java is an object. Even an array is an Object. Every class creates instances that are objects. There is no way of defining just a function / method which stays in Java all by itself. There is no way of passing a method as argument or returning a method body for that instance. Since the old days of Swing, we always had written anonymous classes if we wanted to pass some functionality to any method. For example the old event listener code used to look like: someObject.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { //Event listener implementation goes here... } }); Here we wanted to add some custom code to Mouse listener. We defined an anonymous inner class MouseAdapter and created its object. This way we passed some functionality to addMouseListener method. In short, it is not easy to pass plain methods / functionalities in Java that can be passed as arguments. Due to this limitation Java 8 adds a brand new language level feature called Lambda Expressions. Lambda expressions are coming to Java 8 and together with Raoul-Gabriel Urma and Alan Mycroft I . External vs. internal iteration Let's start with something very simple, a list of integers: 1.List<Integer> numbers = Arrays.list(1, 2, 3, 4, 5, 6); and a for cycle that iterates all the items in the list and prints them: 1.for (int number : numbers) { 2.System.out.println(number); 3.} Straightforward as much as common: I don't remember a single day when we haven't write at least one cycle like this. For example ananya puts away her toys after having played with them. It goes on more or less in this way: Me: " ananya, let's put the toys away. Is there a toy on the ground"
  • 2. ananya: "Yes, the ball" Me: "Ok, put the ball in the box. Is there something else?" ananya: "Yes, there is my doll" Me: "Ok, put the doll in the box. Is there something else?" ananya: "Yes, there is my book" Me: "Ok, put the book in the box. Is there something else?" ananya: "No, nothing else" Me: "Fine, we are done" This is exactly what we do everyday with our Java collections. We iterate the collection externally, explicitly pulling out and processing the items one by one. It would be far better for me if I could tell to ananya just: "put inside the box all the toys that are on the ground". There are two other reasons, why an internal iteration is preferable: first ananya could choose to take at the same time the doll with one hand and the ball with the other and second she could decide to take the objects closest to the box first and then the others. In the same way using an internal iteration the JIT compiler could optimize it processing the items in parallel or in a different order. These optimizations are impossible if we iterate the collection externally as we are used to do in Java and more in general with the imperative programming. So, why don't we iterate internally? I think this is only a bad mental habit caused by the lack of support of this pattern in the Java Collection Framework that in turn has been caused by the verbosity (creation of an anonymous inner class) that this implies in pre-8 Java. Something like this: 1.numbers.forEach(new Consumer<Integer>() { 2.public void accept(Integer value) { 3.System.out.println(value); 4.} 5.}); Structure of Lambda Expressions Let’s check the structure of lambda expressions. A lambda expression can have zero, one or more parameters. The type of the parameters can be explicitly declared or it can be inferred from the context. e.g. (int a) is same as just (a) Parameters are enclosed in parentheses and separated by commas. e.g. (a, b) or (int a, int b)or (String a, int b, float c) Empty parentheses are used to represent an empty set of parameters. e.g. () -> 42 When there is a single parameter, if its type is inferred, it is not mandatory to use parentheses. e.g. a -> return a*a The body of the lambda expressions can contain zero, one or more statements. If body of lambda expression has single statement curly brackets are not mandatory and the return type of the anonymous function is the same as that of the body expression. When there is more than one statement in body than these must be enclosed in curly brackets (a code block) and the return type of the anonymous function is the same as the type of the value returned within the code block, or void if nothing is returned.
  • 3. What are Functional Interfaces? In Java, a Marker interface is an interface with no methods or fields declaration. In simple words, marker interface is an empty interface. Similarly, a Functional Interface is an interface with just one abstract method declared in it. java.lang.Runnable is an example of a Functional Interface. There is only one method void run()declared in Runnable interface. Similarly ActionListener interface is also a Functional Interface. We use Anonymous inner classes to instantiate objects of functional interface. With Lambda expressions, this can be simplified. Each lambda expression can be implicitly assigned to one of the interface called Functional interface. For example we can create Runnable interface’s reference from lambda expression like below: Runnable r = () -> System.out.println("hello world"); This type of conversion is automatically taken care by compiler when we dont specify the functional interface. For example: new Thread( () -> System.out.println("hello world") ).start(); So in above code, compiler automatically deduced that lambda expression can be casted to Runnable interface from Thread class’s constructor signature public Thread(Runnable r) { }. Few examples of lambda expressions and their functional interface: Consumer<Integer> c = (int x) -> { System.out.println(x) }; BiConsumer<Integer, String> b = (Integer x, String y) -> System.out.println(x + " : " + y); Predicate<String> p = (String s) -> { s == null }; @FunctionalInterface is a new interface added in Java 8 to indicate that an interface type declaration is intended to be a functional interface as defined by the Java Language Specification. Java 8 also declared number of Functional Interfaces that can be used by Lambda expressions. @FunctionalInterface can be used for compiler level errors when the interface you have annotated is not a valid Functional Interface. Following is an example of custom defined Functional interface. @FunctionalInterface public interface WorkerInterface { public void doSomeWork();
  • 4. } As its definition says, Functional Interfaces can have only one abstract method. If you try to add one more abstract method in it, it throws compile time error. For example: @FunctionalInterface public interface WorkerInterface { public void doSomeWork(); public void doSomeMoreWork(); } Error: Unexpected @FunctionalInterface annotation @FunctionalInterface ^ WorkerInterface is not a functional interface multiple non-overriding abstract methods found in interface WorkerInterface 1 error Once the Functional interface is defined, we can simply use it in our API and take advantage of Lambda expressions. For example: //define a functional interface @FunctionalInterface public interface WorkerInterface { public void doSomeWork(); } public class WorkerInterfaceTest { public static void execute(WorkerInterface worker) { worker.doSomeWork(); } public static void main(String [] args) { //invoke doSomeWork using Annonymous class execute(new WorkerInterface() { @Override public void doSomeWork() { System.out.println("Worker invoked using Anonymous class"); } }); //invoke doSomeWork using Lambda expression
  • 5. execute( () -> System.out.println("Worker invoked using Lambda expression") ); } } Output: Worker invoked using Anonymous class Worker invoked using Lambda expression Here we created our own Functional interface and used to with lambda expressions. execute() method can now take lambda expressions as argument. In Java 8 lambda expressions allow to achieve the same result in a less verbose and more readable way: 1.numbers.forEach((Integer value) -> System.out.println(value)); The lambda expression is made of two parts the one on the left of the arrow symbol (->) listing its parameters and the one on the right containing its body. In this case the compiler automatically figures out that the lambda expression has the same signature of the only non implemented method of the Consumer interface (that for this reason is called a functional interface) and treat the first as it was an instance of the second, even if the generated bytecode could potentially be different. The declaration of the types of the lambda expression arguments can be, in the biggest part of cases, inferred by the compiler and then omitted as it follows: 1.numbers.forEach(value -> System.out.println(value)); But we can rewrite this last statement even more concisely using a method reference, another feature introduced in Java 8. More in details in Java 8 it is possible to reference both a static and an instance a method using the new :: operator as in: 1.numbers.forEach(System.out::println); In this way, with a process that in functional programming is known as eta expansion, the name of the method is "expanded" by the compiler in the method itself that, as we have already seen, has the same signature of the only abstract method of the Consumer functional interface and then can be in turn converted in an instance of it. Lambda expression adds that missing link of functional programming to Java. in Java, the lambda expressions are represented as objects, and so they must be bound to a particular object type known as a functional interface.
  • 6. Passing behaviors, not only values :- What we have seen in the former example is the main and possibly the only reason why lambda expressions are so useful. Passing a lambda expression to another function allow us to pass not only values but also behaviors and this enable to dramatically raise the level of our abstraction and then project more generic, flexible and reusable API. Let's reenforce this with a further example: starting with the usual list of Integer 1.List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); we are requested to write a method that sums all the Integers in the list as for instance: 1.public int sumAll(List<Integer> numbers) { 2.int total = 0; 3.for (int number : numbers) { 4.total += number; 5.} 6.return total; 7.} The day after a manager comes to our cubicle and tells you that the business also requires to have a function that sums only the even number in the list. So what is the quickest thing we could do? Easy. Just copy and paste the former method and add to it the required filtering condition: 01.public int sumAllEven(List<Integer> numbers) { 02.int total = 0; 03.for (int number : numbers) { 04.if (number % 2 == 0) { 05.total += number; 06.} 07.} 08.return total; 09.} Another day, another requirement: this time they need to sum the numbers in the list again but only if they are greater than 3. So what could we do? Well, we could again copy and paste the former method and just change that boolean condition ... but it feels so dirty, isn't it? Now, following the "First Write, Second Copy, Third Refactor" principle it is time to wonder if there is a smarter and more generic way to do this. In this case implementing an higher- order function accepting together with the list also a Predicate (another functional interface added in Java 8) that defines how to filter the numbers in the list itself before to sum them up.
  • 7. 01.public int sumAll(List<Integer> numbers, Predicate<Integer> p) { 02.int total = 0; 03.for (int number : numbers) { 04.if (p.test(number)) { 05.total += number; 06.} 07.} 08.return total; 09.} In other words we are passing to the method not only the data (the list of numbers) but also a behavior (the Predicate) defining how to use them. In this way we can satisfy all the 3 requirements with a single more generic and then more reusable method: 1.sumAll(numbers, n -> true); 2.sumAll(numbers, n -> n % 2 == 0); 3.sumAll(numbers, n -> n > 3); Examples of Lambda Expressions : Thread can be initialized like following: //Old way: new Thread(new Runnable() { @Override public void run() { System.out.println("Hello from thread"); } }).start(); //New way: new Thread( () -> System.out.println("Hello from thread") ).start(); The event handling can be done with Java 8 using lambda expression. Following code we show both old and new way of adding ActionListener to a UI component. //Old way: button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("The button was clicked using old fashion code!");
  • 8. } }); //New way: button.addActionListener( (e) -> { System.out.println("The button was clicked. From lambda expressions !"); }); Simple code to print all elements of given array. Note there is one more way of using lambda expression. In below example we use the usual way of creating lambda expression using arrow syntax and also we used a brand new double colon (::) operator that Java 8 has to convert a normal method into lambda expression. //Old way: List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7); for(Integer n: list) { System.out.println(n); } //New way: List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7); list.forEach(n -> System.out.println(n)); //or we can use :: double colon operator in Java 8 list.forEach(System.out::println); In this example we use Predicate functional interface to create a test and print the elements that pass the test. This way you can provide the logic using lambda expression and do something based on it. import java.util.Arrays; import java.util.List; import java.util.function.Predicate; public class Main { public static void main(String [] a) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7); System.out.println("Print all numbers:"); evaluate(list, (n)->true); System.out.println("Print no numbers:"); evaluate(list, (n)->false); System.out.println("Print even numbers:");
  • 9. evaluate(list, (n)-> n%2 == 0 ); System.out.println("Print odd numbers:"); evaluate(list, (n)-> n%2 == 1 ); System.out.println("Print numbers greater than 5:"); evaluate(list, (n)-> n > 5 ); } public static void evaluate(List<Integer> list, Predicate<Integer> predicate) { for(Integer n: list) { if(predicate.test(n)) { System.out.println(n + " "); } } } } Output: Print all numbers: 1 2 3 4 5 6 7 Print no numbers: Print even numbers: 2 4 6 Print odd numbers: 1 3 5 7 Print numbers greater than 5: 6 7 Some wizardry using Lambda expression to print square of each element of a list. Notice we used .stream() method to convert regular list into a steam. Java 8 added some awesome Stream APIs.java.util.stream.Stream interface comes with tons of useful methods which can be used along with lambda expression to do some voodoo. We passed a lambda expression x -> x*x to map() method which applies this to all elements of the stream. After that we use forEach to print the all elements of list. //Old way: List<Integer> list = Arrays.asList(1,2,3,4,5,6,7); for(Integer n : list) { int x = n * n; System.out.println(x); } //New way: List<Integer> list = Arrays.asList(1,2,3,4,5,6,7); list.stream().map((x) -> x*x).forEach(System.out::println); Given a list, sum the square of each element from this list. See how Lambda expression can be used to achieve this in a single statement. This is also a starters example on MapReduce.
  • 10. We used map() to square each element and then reduce() to reduce all elements into single number. //Old way: List<Integer> list = Arrays.asList(1,2,3,4,5,6,7); int sum = 0; for(Integer n : list) { int x = n * n; sum = sum + x; } System.out.println(sum); //New way: List<Integer> list = Arrays.asList(1,2,3,4,5,6,7); int sum = list.stream().map(x -> x*x).reduce((x,y) -> x + y).get(); System.out.println(sum); Difference between Lambda Expression and Anonymous class: One key difference between using Anonymous class and Lambda expression is the use of this keyword. For anonymous class ‘this’ keyword resolves to anonymous class, whereas for lambda expression ‘this’ keyword resolves to enclosing class where lambda is written. Another difference between lambda expression and anonymous class is in the way these two are compiled. Java compiler compiles lambda expressions and convert them into private method of the class. It uses invokedynamic instruction that was added in Java 7 to bind this method dynamically.