SlideShare a Scribd company logo
Java 8 Lambda Expressions
Logan Chien
2
Agenda
●
Lambda Expression and Closure
●
Stream and Operations
●
Parallelism
●
Functional Interface
3
Introduction
4
Background
Before Java 8, there were anonymous classes:
JButton btn = new JButton("Click");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
System.out.println("Button clicked!");
}
});
5
Lambda Expressions
It is cumbersome to write anonymous classes in
many cases. Thus, lambda expressions are
introduced:
JButton btn = new JButton("Click");
btn.addActionListener(
evt -> System.out.println("Button clicked!"));
6
Lambda Syntax
●
No arguments:
●
One argument:
●
Two arguments:
●
With explicit argument types:
●
Multiple statements:
() -> System.out.println("Hello")
s -> System.out.println(s)
(x, y) -> x + y
(Integer x, Integer y) -> x + y
(x, y) -> {
System.out.println(x);
System.out.println(y);
return (x + y);
}
7
Lambda Syntax Sugar 1/2
Method reference
public class HashFunction {
public static int compute1(Object obj) { /*...*/ }
public static int compute2(int a, int b) { /*...*/ }
}
HashFunc::compute1
(x) -> HashFunc::compute1(x)
HashFunc::compute2
(x, y) -> HashFunc::compute2(x, y)
1
2
8
Lambda Syntax Sugar 2/2
Constructor reference
String::new () -> new String()
(x) -> new String(x)
(x, y) -> new String(x, y)
(x, y, z) -> new String(x, y, z)
int[]::new (s) -> new int[s]
1
2
9
Lambda Expression vs. Closure
●
Lambda expression
– A piece of the source code have the semantics like
anonymous classes.
– Evaluated to a closure object in the run-time.
●
Closure
– The run-time object that contains the captured
variables and an associated method.
10
Capture Variable 1/3
●
We can refer to local variables in lambda
expressions.
– The referred local variables should be either final
or effectively final.
●
Evaluation of lambda expression will copy the
referred local variables to closure objects.
11
Capture Variable 2/3
import java.util.stream.*;
import java.util.function.*;
public class CaptureExample {
public static IntUnaryOperator addBy(int n) {
return (x) -> x + n;
}
public static void main(String[] args) {
IntStream.of(1, 2, 3).map(addBy(1))
.map(addBy(2))
.forEach(System.out::println);
}
}
Capture variable11
2 The lambda expression is evaluated twice. Thus, two
closure objects are returned.
12
Capture Variable 3/3
import java.util.function.*;
public class NonEffectivelyFinalExample {
public static IntUnaryOperator foo(int a, int n) {
if (a < 0) {
return (x) -> x + n;
}
n -= a;
return (x) -> x + n;
}
}
NonEffectivelyFinalExample.java:5: error: local variables referenced from
a lambda expression must be final or effectively final
return (x) -> x + n;
^
NonEffectivelyFinalExample.java:8: error: local variables referenced from
a lambda expression must be final or effectively final
return (x) -> x + n;
^
2 errors
Not effectively final
13
Type Inference
What is the type for following lambda
expression?
Ans: It depends on the context. Java compiler
will infer the type automatically.
(x) -> System.out.println(x)
IntConsumer f = (x) -> System.out.println(x);
// (int) -> void
DoubleConsumer g = (x) -> System.out.println(x);
// (double) -> void
14
Questions?
15
Stream & Operations
16
Big Picture
How to Use Lambdas?
●
Stream – Create a stream from the collections,
arrays, etc.
●
Lazy operations – Operations that will be applied
to stream elements on demand.
●
Eager operations – Operations that will trigger
the evaluations.
– Enumerators, Collectors, etc.
17
Stream
●
Stream is an abstraction of the underlying
data structure.
●
Isolates the data processing and control flow.
●
Abstracts the intermediate data structures.
●
Abstracts the lazy evaluation of operations.
18
How to Create Stream?
●
From programmer-specified elements
●
From arrays
●
From java.util.Collection
●
From java.util.Map
java.util.Stream.of(...)
java.util.Arrays.stream(array)
java.util.Collection.stream()
java.util.Collection.parallelStream()
java.util.Map.entrySet().stream()
java.util.Map.values().stream()
19
Operations
●
Lazy evaluation
– filter
– map
– flatMap
– peek
– ... etc
●
Eager evaluation
– count
– forEach
– toArray
– reduce
– collect
– ... etc
Tips: Check the return type. The lazy operations will return Stream.
20
Lazy Operations
21
filter() 1/2
●
filter() takes a predicate function
●
If the predicate function returns false, then
the element will be removed from the
stream.
1 2 3 4 5
1 3 5
Input Stream
Output Stream
…
…
filter(x -> x % 2 != 0)
22
filter() 2/2
import java.util.stream.*;
public class FilterExample {
public static void main(String[] args) {
Stream.of(1, 2, 3, 4, 5)
.filter(x -> x % 2 != 0)
.forEach(System.out::println);
}
}
1 2 3 4 5
1 3 5
Input Stream
Output Stream
…
…
filter(x -> x % 2 != 0)
23
map() 1/2
●
map() takes an unary function which will
convert one element to another element.
1 3 5Input Stream
Output Stream
…
…S:0 S:1 S:2
map(x -> "S:" + x / 2)
24
import java.util.stream.*;
public class MapExample {
public static void main(String[] args) {
Stream.of(1, 3, 5)
.map(x -> "S:" + x / 2)
.forEach(System.out::println);
}
}
map() 2/2
1 3 5Input Stream
Output Stream
…
…S:0 S:1 S:2
map(x -> "S:" + x / 2)
Integer
String
25
flatMap() 1/4
●
flatMap() takes an unary function.
●
The unary function will take an element and
return a stream.
●
flatMap() will concatenate these streams.
1 2 3Input Stream
Output Stream
…
…0 0 1 0 1 2
flatMap(x -> IntStream.range(0, x).boxed())
26
flatMap() 2/4
import java.util.stream.*;
public class FlatMapExample1 {
public static void main(String[] args) {
Stream.of(1, 2, 3)
.flatMap(x -> IntStream.range(0, x).boxed())
.forEach(System.out::println);
}
}
1 2 3Input Stream
Output Stream
…
…0 0 1 0 1 2
flatMap(x -> IntStream.range(0, x).boxed())
27
flatMap() 3/4
A
B
C
a
b bb bbb
c cc
HashMap<String, String[]>
Key Value
28
flatMap() 4/4
import java.util.*;
import java.util.stream.*;
public class FlatMapExample2 {
public static void main(String[] args) {
HashMap<String, String[]> m =
new HashMap<String, String[]>();
m.put("A", new String[]{"a"});
m.put("B", new String[]{"b", "bb", "bbb"});
m.put("C", new String[]{"c", "cc"});
m.entrySet().stream()
.flatMap(e -> Arrays.stream(e.getValue()))
.forEach(System.out::println);
}
}
29
peek() 1/3
●
peek() is the debug routine.
– e.g. Print the value during the lazy evaluation.
●
It will call the closure method with an element.
– You can print the element.
– You can manipulate the object (but not
recommended.)
30
peek() 2/3
import java.util.stream.*;
public class PeekExample1 {
public static void main(String[] args) {
Stream.of(1, 2, 3)
.map(x -> x * 2)
.peek(x -> System.out.println("a:" + x))
.map(x -> x + 1)
.peek(x -> System.out.println("b:" + x))
.forEach(System.out::println);
}
};
a:2
b:3
3
a:4
b:5
5
a:6
b:7
7
Output
31
peek() 3/3
import java.util.stream.*;
class Num {
private int value;
public Num(int i) { value = i; }
public int get() { return value; }
public void set(int i) { value = i; }
};
public class PeekExample2 {
public static void main(String[] args) {
Stream.of(new Num(1), new Num(2), new Num(3))
.peek(x -> x.set(5))
.forEach(x -> System.out.println(x.get()));
}
};
5
5
5
Output
32
Remarks 1/2
●
Lazy operations won't be executed until they
are triggered by an eager operation.
– This example will not print any numbers.
– The lambda expression is evaluated.
– The method in the closure is NOT invoked.
Stream.of(1, 2, 3).filter(x -> {
System.out.println(x);
return true;
});
33
Remarks 2/2
●
It is suggested to use pure functions (i.e. no
side-effects) for these operations.
– It is hard to predict the behavior when we have
both mutability and lazy evaluation.
– Mutable + Lazy Evaluation = Disaster
– Except: For debug purpose only.
34
Eager Operations
35
forEach()
forEach() will iterate through the stream and
invoke the closure method with each element.
Stream.of(1, 2, 3, 4, 5)
.forEach(x -> System.out.println("GOT:" + x));
36
count()
count() counts the number of elements in a
stream.
import java.util.stream.*;
public class CountExample {
public static boolean isPrime(int i) {
if (i > 2 && i % 2 == 0) return false;
for (int p = 3; p * p <= i; p += 2)
if (i % p == 0) return false;
return true;
}
public static void main(String[] args) {
long num = IntStream.range(2, 100).filter(Count::isPrime).count();
System.out.println("Num primes in [2,100) = " + num);
}
}
37
toArray()
toArray() collects all of the elements from a
stream and put them in a java.lang.Object
array. import java.util.stream.*;
public class ToArrayExample {
public static void main(String[] args) {
Object[] array = Stream.of("apple", "bear", "bat", "cat")
.filter(x -> x.startsWith("b")).toArray();
for (Object s : array) {
System.out.println((String)s);
}
}
}
38
reduce() 1/4
●
There are three overloaded methods
●
Accumulator should be associative.
1
2
3
Optional<T> reduce(BinaryOperator<T> acc)
T reduce(T id, BinaryOperator<T> acc)
<U> U reduce(U id, BiFunction<U, ? super T, U> acc,
BinaryOperator<U> combiner)
39
reduce() 2/4
import java.util.Optional;
import java.util.stream.*;
public class ReduceExample1 {
public static Optional<Integer> sum(Stream<Integer> s) {
return s.reduce((x, y) -> x + y);
}
public static void main(String[] args) {
System.out.println(sum(Stream.of()));
System.out.println(sum(Stream.of(1)));
System.out.println(sum(Stream.of(1, 2)));
}
}
Output
Optional.empty
Optional[1]
Optional[3]
40
reduce() 3/4
import java.util.Optional;
import java.util.stream.*;
public class ReduceExample2 {
public static int sum(Stream<Integer> s) {
return s.reduce(0, (x, y) -> x + y);
}
public static void main(String[] args) {
System.out.println(sum(Stream.of()));
System.out.println(sum(Stream.of(1)));
System.out.println(sum(Stream.of(1, 2)));
}
}
Output
0
1
3
41
collect()
●
collect() takes a collector object and send
each element to the collector.
●
It allows the run-time to build the final data
structure gradually.
42
Common Collectors
●
Collectors.toList()
●
Collectors.toSet()
●
Colloctors.groupingBy()
●
Collectors.joining()
●
Find more in java.util.stream.Collectors.
43
collect(toList())
import java.util.List;
import java.util.stream.*;
public class CollectToListExample {
public static void main(String[] args) {
List<Integer> odds = Stream.of(1, 2, 3, 4, 5)
.filter(x -> x % 2 != 0)
.collect(Collectors.toList());
for (Integer i : odds) {
System.out.println(i);
}
}
}
44
collect(toSet())
import java.util.Set;
import java.util.stream.*;
public class CollectToSetExample {
public static void main(String[] args) {
Set<Integer> congs = Stream.of(1, 2, 3, 4, 5)
.map(x -> x % 2)
.collect(Collectors.toSet());
for (Integer i : congs) {
System.out.println(i);
}
}
}
45
collect(groupingBy())
import java.util.*;
import java.util.stream.*;
public class CollectGroupingByExample {
public static void main(String[] args) {
Map<String, List<Integer>> groups =
Stream.of(1, 2, 3, 4, 5)
.collect(Collectors.groupingBy(
x -> x % 2 == 0 ? "even" : "odd"));
for (Map.Entry<String, List<Integer>> e : groups.entrySet()) {
System.out.println(e.getKey() + ":" + e.getValue());
}
}
}
46
collect(joining())
import java.util.stream.*;
public class CollectJoinExample {
public static void main(String[] args) {
String s = Stream.of(1, 2, 3, 4, 5)
.map(x -> x.toString())
.collect(Collectors.joining(", "));
System.out.println(s);
}
}
Output
1, 2, 3, 4, 5
47
Specialized Types
48
Specialized Types
●
To reduce box/unbox overhead, several
specialized types for int, long, and double are
provided.
– Streams
– Function Interfaces
– Predicate
– Collector
49
Specialized Stream
●
3 specialized (unboxed) streams:
– DoubleStream, IntStream, and LongStream
●
Box streams (convert from TypeStream to Stream<T>)
– Call IntStream.boxed() method.
●
Unbox streams (convert from Stream<T> to IntStream)
– Call Stream<T>.mapToInt() method.
50
Specialized Functions
●
One argument and one return value
– Function<T, R>
– IntFunction<R>
– ToIntFunction<T>
– LongToIntFunction
– UnaryOperator<T>
– IntUnaryOperator
R apply(T t)
R apply(int t)
int applyAsInt(T t)
R apply(R t)
int applyAsInt(int t)
int applyAsInt(long t)
51
Specialized Functions
●
Two arguments and one return value
– BiFunction<T, U, R>
– ToIntBiFunction<T, U>
– BinaryOperator<T>
– IntBinaryOperator
R apply(T t, U u)
int applyAsInt(T t, U u)
R apply(T t, U u)
int applyAsInt(int t, int u)
52
Specialized Predicate
●
Specialized stream requires specialized
predicates.
– allMatch, anyMatch, filter, noneMatch
●
Comparison
– Predicate<T>
– IntPredicate
boolean test(T t)
boolean test(int t)
53
Specialized Collectors Methods
●
Average
●
Summerizing
●
Summing
Collector<T, ?, Double>
averagingInt(ToIntFunction<? super T> mapper)
Collector<T, ?, IntSummaryStatistics>
summerizingInt(ToIntFunction<? super T> mapper)
Collector<T, ?, Integer>
summingInt(ToIntFunction<? super T> mapper)
54
Questions?
55
Parallelism
56
Parallelism
●
If we limit ourselves to this restricted
programming style, then we can (almost) get
parallelism for free.
●
Call parallel() to convert a stream to
parallel stream.
57
Parallelism Example
public class ParallelExample {
public static long sumSeq(long[] array) {
return Arrays.stream(array).sum();
}
public static long sumPar(long[] array) {
return Arrays.stream(array).parallel().sum();
}
public static void main(String[] args) {
int size = 40000000;
long[] array = new long[size];
for (int i = 0; i < size; ++i) array[i] = i;
long startSeq = System.nanoTime();
long resSeq = sumSeq(array);
long durationSeq = System.nanoTime() - startSeq;
long startPar = System.nanoTime();
long resPar = sumPar(array);
long durationPar = System.nanoTime() - startPar;
}
}
Output
resultSeq: 799999980000000
resultPar: 799999980000000
durationSeq: 58598502
durationPar: 21206305
58
Questions?
59
Functional Interface
60
How to Receive Lambdas?
●
The closure object is an object that can be passed around.
●
The closure class will implement the specified interface.
●
To run the body of the lambda expression, invoke the
corresponding method.
●
The interface should contain exactly one non-default
abstract method.
– Because we can choose arbitrary method name.
61
Functional Interfaces
●
Interfaces with one non-default method.
●
It is suggested to annotate with:
@FunctionalInterface.
@FunctionalInterface
public interface MouseEventListener {
public void accept(MouseEvent evt);
}
panel.registerListener(
evt -> System.out.println("Processed!"));
62
Functional Interfaces
import java.util.HashSet;
public class Panel {
private HashSet<MouseEventListener> listeners =
new HashSet<MouseEventListener>();
public void registerListener(MouseEventListener cb) {
listeners.add(cb);
}
public void notifyListener(MouseEvent evt) {
listeners.forEach(x -> x.accept(evt));
}
}
63
Default Method
●
Problem: The language designer would like to
add functions to interfaces, but it will break
the existing program.
●
Solution: We can specify the default method in
an interface.
– Default methods should only use other abstract
methods, i.e. no field access is allowed.
64
Default Method
●
Default methods will be inherited (and may be
overrided) when the interface is extended.
●
The closest default method will be chosen.
●
To invoke the super default method, use the
super keyword.
●
It is necessary to override one if there are conflicts.
65
Static Method
●
In Java 8, we can write static methods in
interfaces as well.
●
For example, Stream.of() is a notable static
method in the interface.
66
Thanks!
Any questions?

More Related Content

What's hot (20)

PPTX
Functional programming with Java 8
LivePerson
 
PDF
Lambda Expressions in Java | Java Lambda Tutorial | Java Certification Traini...
Edureka!
 
PPTX
Java 8 presentation
Van Huong
 
ODP
Introduction to Java 8
Knoldus Inc.
 
PPTX
java 8 new features
Rohit Verma
 
PPTX
Java 8 features
Maýur Chourasiya
 
PDF
Java 8 features
NexThoughts Technologies
 
PPTX
Java 8 - Features Overview
Sergii Stets
 
PPSX
Collections - Lists, Sets
Hitesh-Java
 
PPTX
Introduction to java 8 stream api
Vladislav sidlyarevich
 
DOCX
JDK,JRE,JVM
Cognizant
 
PDF
Java 8 Stream API. A different way to process collections.
David Gómez García
 
PPT
Introduction to Design Patterns and Singleton
Jonathan Simon
 
PPTX
Java 8 - An Overview
Indrajit Das
 
PDF
Spring Framework - AOP
Dzmitry Naskou
 
PPT
Java 8 Streams
Manvendra Singh
 
PPTX
Java Lambda Expressions.pptx
SameerAhmed593310
 
PDF
Understanding Reactive Programming
Andres Almiray
 
PDF
JUnit & Mockito, first steps
Renato Primavera
 
Functional programming with Java 8
LivePerson
 
Lambda Expressions in Java | Java Lambda Tutorial | Java Certification Traini...
Edureka!
 
Java 8 presentation
Van Huong
 
Introduction to Java 8
Knoldus Inc.
 
java 8 new features
Rohit Verma
 
Java 8 features
Maýur Chourasiya
 
Java 8 features
NexThoughts Technologies
 
Java 8 - Features Overview
Sergii Stets
 
Collections - Lists, Sets
Hitesh-Java
 
Introduction to java 8 stream api
Vladislav sidlyarevich
 
JDK,JRE,JVM
Cognizant
 
Java 8 Stream API. A different way to process collections.
David Gómez García
 
Introduction to Design Patterns and Singleton
Jonathan Simon
 
Java 8 - An Overview
Indrajit Das
 
Spring Framework - AOP
Dzmitry Naskou
 
Java 8 Streams
Manvendra Singh
 
Java Lambda Expressions.pptx
SameerAhmed593310
 
Understanding Reactive Programming
Andres Almiray
 
JUnit & Mockito, first steps
Renato Primavera
 

Similar to Java 8 lambda expressions (20)

PPT
Functional Programming
Olexandra Dmytrenko
 
PDF
Sam wd programs
Soumya Behera
 
PPT
object oriented programming java lectures
MSohaib24
 
PDF
New Functional Features of Java 8
franciscoortin
 
PPT
Oop lecture9 13
Shahriar Robbani
 
PDF
java programming cheatsheet
BD AB
 
PDF
The... Wonderful? World of Lambdas
Esther Lozano
 
PPTX
Is java8a truefunctionallanguage
Samir Chekkal
 
PPTX
Is java8 a true functional programming language
SQLI
 
PPTX
Pj01 4-operators and control flow
SasidharaRaoMarrapu
 
PDF
Functional Programming in Java 8
Omar Bashir
 
PPT
eee2-day4-structures engineering college
2017eee0459
 
PDF
Java Fundamentals
Shalabh Chaudhary
 
PDF
Java Simple Programs
Upender Upr
 
PPTX
Chap2 class,objects contd
raksharao
 
PDF
Class 6 2ciclo
Carlos Alcivar
 
PDF
Matlab solved problems
Make Mannan
 
DOCX
Operators
loidasacueza
 
PPT
Python High Level Functions_Ch 11.ppt
AnishaJ7
 
PDF
Lambda Functions in Java 8
Ganesh Samarthyam
 
Functional Programming
Olexandra Dmytrenko
 
Sam wd programs
Soumya Behera
 
object oriented programming java lectures
MSohaib24
 
New Functional Features of Java 8
franciscoortin
 
Oop lecture9 13
Shahriar Robbani
 
java programming cheatsheet
BD AB
 
The... Wonderful? World of Lambdas
Esther Lozano
 
Is java8a truefunctionallanguage
Samir Chekkal
 
Is java8 a true functional programming language
SQLI
 
Pj01 4-operators and control flow
SasidharaRaoMarrapu
 
Functional Programming in Java 8
Omar Bashir
 
eee2-day4-structures engineering college
2017eee0459
 
Java Fundamentals
Shalabh Chaudhary
 
Java Simple Programs
Upender Upr
 
Chap2 class,objects contd
raksharao
 
Class 6 2ciclo
Carlos Alcivar
 
Matlab solved problems
Make Mannan
 
Operators
loidasacueza
 
Python High Level Functions_Ch 11.ppt
AnishaJ7
 
Lambda Functions in Java 8
Ganesh Samarthyam
 
Ad

Recently uploaded (20)

PPTX
Human Resources Information System (HRIS)
Amity University, Patna
 
PDF
Alexander Marshalov - How to use AI Assistants with your Monitoring system Q2...
VictoriaMetrics
 
PPTX
Writing Better Code - Helping Developers make Decisions.pptx
Lorraine Steyn
 
PDF
Powering GIS with FME and VertiGIS - Peak of Data & AI 2025
Safe Software
 
PDF
iTop VPN With Crack Lifetime Activation Key-CODE
utfefguu
 
PDF
Efficient, Automated Claims Processing Software for Insurers
Insurance Tech Services
 
DOCX
Import Data Form Excel to Tally Services
Tally xperts
 
PPTX
3uTools Full Crack Free Version Download [Latest] 2025
muhammadgurbazkhan
 
PDF
Mobile CMMS Solutions Empowering the Frontline Workforce
CryotosCMMSSoftware
 
PDF
GetOnCRM Speeds Up Agentforce 3 Deployment for Enterprise AI Wins.pdf
GetOnCRM Solutions
 
PPTX
Java Native Memory Leaks: The Hidden Villain Behind JVM Performance Issues
Tier1 app
 
PPTX
MailsDaddy Outlook OST to PST converter.pptx
abhishekdutt366
 
PDF
Alarm in Android-Scheduling Timed Tasks Using AlarmManager in Android.pdf
Nabin Dhakal
 
PPTX
The Role of a PHP Development Company in Modern Web Development
SEO Company for School in Delhi NCR
 
PDF
Beyond Binaries: Understanding Diversity and Allyship in a Global Workplace -...
Imma Valls Bernaus
 
PDF
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
PPTX
MiniTool Power Data Recovery Full Crack Latest 2025
muhammadgurbazkhan
 
PPTX
Engineering the Java Web Application (MVC)
abhishekoza1981
 
PPTX
Fundamentals_of_Microservices_Architecture.pptx
MuhammadUzair504018
 
PPTX
Revolutionizing Code Modernization with AI
KrzysztofKkol1
 
Human Resources Information System (HRIS)
Amity University, Patna
 
Alexander Marshalov - How to use AI Assistants with your Monitoring system Q2...
VictoriaMetrics
 
Writing Better Code - Helping Developers make Decisions.pptx
Lorraine Steyn
 
Powering GIS with FME and VertiGIS - Peak of Data & AI 2025
Safe Software
 
iTop VPN With Crack Lifetime Activation Key-CODE
utfefguu
 
Efficient, Automated Claims Processing Software for Insurers
Insurance Tech Services
 
Import Data Form Excel to Tally Services
Tally xperts
 
3uTools Full Crack Free Version Download [Latest] 2025
muhammadgurbazkhan
 
Mobile CMMS Solutions Empowering the Frontline Workforce
CryotosCMMSSoftware
 
GetOnCRM Speeds Up Agentforce 3 Deployment for Enterprise AI Wins.pdf
GetOnCRM Solutions
 
Java Native Memory Leaks: The Hidden Villain Behind JVM Performance Issues
Tier1 app
 
MailsDaddy Outlook OST to PST converter.pptx
abhishekdutt366
 
Alarm in Android-Scheduling Timed Tasks Using AlarmManager in Android.pdf
Nabin Dhakal
 
The Role of a PHP Development Company in Modern Web Development
SEO Company for School in Delhi NCR
 
Beyond Binaries: Understanding Diversity and Allyship in a Global Workplace -...
Imma Valls Bernaus
 
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
MiniTool Power Data Recovery Full Crack Latest 2025
muhammadgurbazkhan
 
Engineering the Java Web Application (MVC)
abhishekoza1981
 
Fundamentals_of_Microservices_Architecture.pptx
MuhammadUzair504018
 
Revolutionizing Code Modernization with AI
KrzysztofKkol1
 
Ad

Java 8 lambda expressions

  • 1. Java 8 Lambda Expressions Logan Chien
  • 2. 2 Agenda ● Lambda Expression and Closure ● Stream and Operations ● Parallelism ● Functional Interface
  • 4. 4 Background Before Java 8, there were anonymous classes: JButton btn = new JButton("Click"); btn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { System.out.println("Button clicked!"); } });
  • 5. 5 Lambda Expressions It is cumbersome to write anonymous classes in many cases. Thus, lambda expressions are introduced: JButton btn = new JButton("Click"); btn.addActionListener( evt -> System.out.println("Button clicked!"));
  • 6. 6 Lambda Syntax ● No arguments: ● One argument: ● Two arguments: ● With explicit argument types: ● Multiple statements: () -> System.out.println("Hello") s -> System.out.println(s) (x, y) -> x + y (Integer x, Integer y) -> x + y (x, y) -> { System.out.println(x); System.out.println(y); return (x + y); }
  • 7. 7 Lambda Syntax Sugar 1/2 Method reference public class HashFunction { public static int compute1(Object obj) { /*...*/ } public static int compute2(int a, int b) { /*...*/ } } HashFunc::compute1 (x) -> HashFunc::compute1(x) HashFunc::compute2 (x, y) -> HashFunc::compute2(x, y) 1 2
  • 8. 8 Lambda Syntax Sugar 2/2 Constructor reference String::new () -> new String() (x) -> new String(x) (x, y) -> new String(x, y) (x, y, z) -> new String(x, y, z) int[]::new (s) -> new int[s] 1 2
  • 9. 9 Lambda Expression vs. Closure ● Lambda expression – A piece of the source code have the semantics like anonymous classes. – Evaluated to a closure object in the run-time. ● Closure – The run-time object that contains the captured variables and an associated method.
  • 10. 10 Capture Variable 1/3 ● We can refer to local variables in lambda expressions. – The referred local variables should be either final or effectively final. ● Evaluation of lambda expression will copy the referred local variables to closure objects.
  • 11. 11 Capture Variable 2/3 import java.util.stream.*; import java.util.function.*; public class CaptureExample { public static IntUnaryOperator addBy(int n) { return (x) -> x + n; } public static void main(String[] args) { IntStream.of(1, 2, 3).map(addBy(1)) .map(addBy(2)) .forEach(System.out::println); } } Capture variable11 2 The lambda expression is evaluated twice. Thus, two closure objects are returned.
  • 12. 12 Capture Variable 3/3 import java.util.function.*; public class NonEffectivelyFinalExample { public static IntUnaryOperator foo(int a, int n) { if (a < 0) { return (x) -> x + n; } n -= a; return (x) -> x + n; } } NonEffectivelyFinalExample.java:5: error: local variables referenced from a lambda expression must be final or effectively final return (x) -> x + n; ^ NonEffectivelyFinalExample.java:8: error: local variables referenced from a lambda expression must be final or effectively final return (x) -> x + n; ^ 2 errors Not effectively final
  • 13. 13 Type Inference What is the type for following lambda expression? Ans: It depends on the context. Java compiler will infer the type automatically. (x) -> System.out.println(x) IntConsumer f = (x) -> System.out.println(x); // (int) -> void DoubleConsumer g = (x) -> System.out.println(x); // (double) -> void
  • 16. 16 Big Picture How to Use Lambdas? ● Stream – Create a stream from the collections, arrays, etc. ● Lazy operations – Operations that will be applied to stream elements on demand. ● Eager operations – Operations that will trigger the evaluations. – Enumerators, Collectors, etc.
  • 17. 17 Stream ● Stream is an abstraction of the underlying data structure. ● Isolates the data processing and control flow. ● Abstracts the intermediate data structures. ● Abstracts the lazy evaluation of operations.
  • 18. 18 How to Create Stream? ● From programmer-specified elements ● From arrays ● From java.util.Collection ● From java.util.Map java.util.Stream.of(...) java.util.Arrays.stream(array) java.util.Collection.stream() java.util.Collection.parallelStream() java.util.Map.entrySet().stream() java.util.Map.values().stream()
  • 19. 19 Operations ● Lazy evaluation – filter – map – flatMap – peek – ... etc ● Eager evaluation – count – forEach – toArray – reduce – collect – ... etc Tips: Check the return type. The lazy operations will return Stream.
  • 21. 21 filter() 1/2 ● filter() takes a predicate function ● If the predicate function returns false, then the element will be removed from the stream. 1 2 3 4 5 1 3 5 Input Stream Output Stream … … filter(x -> x % 2 != 0)
  • 22. 22 filter() 2/2 import java.util.stream.*; public class FilterExample { public static void main(String[] args) { Stream.of(1, 2, 3, 4, 5) .filter(x -> x % 2 != 0) .forEach(System.out::println); } } 1 2 3 4 5 1 3 5 Input Stream Output Stream … … filter(x -> x % 2 != 0)
  • 23. 23 map() 1/2 ● map() takes an unary function which will convert one element to another element. 1 3 5Input Stream Output Stream … …S:0 S:1 S:2 map(x -> "S:" + x / 2)
  • 24. 24 import java.util.stream.*; public class MapExample { public static void main(String[] args) { Stream.of(1, 3, 5) .map(x -> "S:" + x / 2) .forEach(System.out::println); } } map() 2/2 1 3 5Input Stream Output Stream … …S:0 S:1 S:2 map(x -> "S:" + x / 2) Integer String
  • 25. 25 flatMap() 1/4 ● flatMap() takes an unary function. ● The unary function will take an element and return a stream. ● flatMap() will concatenate these streams. 1 2 3Input Stream Output Stream … …0 0 1 0 1 2 flatMap(x -> IntStream.range(0, x).boxed())
  • 26. 26 flatMap() 2/4 import java.util.stream.*; public class FlatMapExample1 { public static void main(String[] args) { Stream.of(1, 2, 3) .flatMap(x -> IntStream.range(0, x).boxed()) .forEach(System.out::println); } } 1 2 3Input Stream Output Stream … …0 0 1 0 1 2 flatMap(x -> IntStream.range(0, x).boxed())
  • 27. 27 flatMap() 3/4 A B C a b bb bbb c cc HashMap<String, String[]> Key Value
  • 28. 28 flatMap() 4/4 import java.util.*; import java.util.stream.*; public class FlatMapExample2 { public static void main(String[] args) { HashMap<String, String[]> m = new HashMap<String, String[]>(); m.put("A", new String[]{"a"}); m.put("B", new String[]{"b", "bb", "bbb"}); m.put("C", new String[]{"c", "cc"}); m.entrySet().stream() .flatMap(e -> Arrays.stream(e.getValue())) .forEach(System.out::println); } }
  • 29. 29 peek() 1/3 ● peek() is the debug routine. – e.g. Print the value during the lazy evaluation. ● It will call the closure method with an element. – You can print the element. – You can manipulate the object (but not recommended.)
  • 30. 30 peek() 2/3 import java.util.stream.*; public class PeekExample1 { public static void main(String[] args) { Stream.of(1, 2, 3) .map(x -> x * 2) .peek(x -> System.out.println("a:" + x)) .map(x -> x + 1) .peek(x -> System.out.println("b:" + x)) .forEach(System.out::println); } }; a:2 b:3 3 a:4 b:5 5 a:6 b:7 7 Output
  • 31. 31 peek() 3/3 import java.util.stream.*; class Num { private int value; public Num(int i) { value = i; } public int get() { return value; } public void set(int i) { value = i; } }; public class PeekExample2 { public static void main(String[] args) { Stream.of(new Num(1), new Num(2), new Num(3)) .peek(x -> x.set(5)) .forEach(x -> System.out.println(x.get())); } }; 5 5 5 Output
  • 32. 32 Remarks 1/2 ● Lazy operations won't be executed until they are triggered by an eager operation. – This example will not print any numbers. – The lambda expression is evaluated. – The method in the closure is NOT invoked. Stream.of(1, 2, 3).filter(x -> { System.out.println(x); return true; });
  • 33. 33 Remarks 2/2 ● It is suggested to use pure functions (i.e. no side-effects) for these operations. – It is hard to predict the behavior when we have both mutability and lazy evaluation. – Mutable + Lazy Evaluation = Disaster – Except: For debug purpose only.
  • 35. 35 forEach() forEach() will iterate through the stream and invoke the closure method with each element. Stream.of(1, 2, 3, 4, 5) .forEach(x -> System.out.println("GOT:" + x));
  • 36. 36 count() count() counts the number of elements in a stream. import java.util.stream.*; public class CountExample { public static boolean isPrime(int i) { if (i > 2 && i % 2 == 0) return false; for (int p = 3; p * p <= i; p += 2) if (i % p == 0) return false; return true; } public static void main(String[] args) { long num = IntStream.range(2, 100).filter(Count::isPrime).count(); System.out.println("Num primes in [2,100) = " + num); } }
  • 37. 37 toArray() toArray() collects all of the elements from a stream and put them in a java.lang.Object array. import java.util.stream.*; public class ToArrayExample { public static void main(String[] args) { Object[] array = Stream.of("apple", "bear", "bat", "cat") .filter(x -> x.startsWith("b")).toArray(); for (Object s : array) { System.out.println((String)s); } } }
  • 38. 38 reduce() 1/4 ● There are three overloaded methods ● Accumulator should be associative. 1 2 3 Optional<T> reduce(BinaryOperator<T> acc) T reduce(T id, BinaryOperator<T> acc) <U> U reduce(U id, BiFunction<U, ? super T, U> acc, BinaryOperator<U> combiner)
  • 39. 39 reduce() 2/4 import java.util.Optional; import java.util.stream.*; public class ReduceExample1 { public static Optional<Integer> sum(Stream<Integer> s) { return s.reduce((x, y) -> x + y); } public static void main(String[] args) { System.out.println(sum(Stream.of())); System.out.println(sum(Stream.of(1))); System.out.println(sum(Stream.of(1, 2))); } } Output Optional.empty Optional[1] Optional[3]
  • 40. 40 reduce() 3/4 import java.util.Optional; import java.util.stream.*; public class ReduceExample2 { public static int sum(Stream<Integer> s) { return s.reduce(0, (x, y) -> x + y); } public static void main(String[] args) { System.out.println(sum(Stream.of())); System.out.println(sum(Stream.of(1))); System.out.println(sum(Stream.of(1, 2))); } } Output 0 1 3
  • 41. 41 collect() ● collect() takes a collector object and send each element to the collector. ● It allows the run-time to build the final data structure gradually.
  • 43. 43 collect(toList()) import java.util.List; import java.util.stream.*; public class CollectToListExample { public static void main(String[] args) { List<Integer> odds = Stream.of(1, 2, 3, 4, 5) .filter(x -> x % 2 != 0) .collect(Collectors.toList()); for (Integer i : odds) { System.out.println(i); } } }
  • 44. 44 collect(toSet()) import java.util.Set; import java.util.stream.*; public class CollectToSetExample { public static void main(String[] args) { Set<Integer> congs = Stream.of(1, 2, 3, 4, 5) .map(x -> x % 2) .collect(Collectors.toSet()); for (Integer i : congs) { System.out.println(i); } } }
  • 45. 45 collect(groupingBy()) import java.util.*; import java.util.stream.*; public class CollectGroupingByExample { public static void main(String[] args) { Map<String, List<Integer>> groups = Stream.of(1, 2, 3, 4, 5) .collect(Collectors.groupingBy( x -> x % 2 == 0 ? "even" : "odd")); for (Map.Entry<String, List<Integer>> e : groups.entrySet()) { System.out.println(e.getKey() + ":" + e.getValue()); } } }
  • 46. 46 collect(joining()) import java.util.stream.*; public class CollectJoinExample { public static void main(String[] args) { String s = Stream.of(1, 2, 3, 4, 5) .map(x -> x.toString()) .collect(Collectors.joining(", ")); System.out.println(s); } } Output 1, 2, 3, 4, 5
  • 48. 48 Specialized Types ● To reduce box/unbox overhead, several specialized types for int, long, and double are provided. – Streams – Function Interfaces – Predicate – Collector
  • 49. 49 Specialized Stream ● 3 specialized (unboxed) streams: – DoubleStream, IntStream, and LongStream ● Box streams (convert from TypeStream to Stream<T>) – Call IntStream.boxed() method. ● Unbox streams (convert from Stream<T> to IntStream) – Call Stream<T>.mapToInt() method.
  • 50. 50 Specialized Functions ● One argument and one return value – Function<T, R> – IntFunction<R> – ToIntFunction<T> – LongToIntFunction – UnaryOperator<T> – IntUnaryOperator R apply(T t) R apply(int t) int applyAsInt(T t) R apply(R t) int applyAsInt(int t) int applyAsInt(long t)
  • 51. 51 Specialized Functions ● Two arguments and one return value – BiFunction<T, U, R> – ToIntBiFunction<T, U> – BinaryOperator<T> – IntBinaryOperator R apply(T t, U u) int applyAsInt(T t, U u) R apply(T t, U u) int applyAsInt(int t, int u)
  • 52. 52 Specialized Predicate ● Specialized stream requires specialized predicates. – allMatch, anyMatch, filter, noneMatch ● Comparison – Predicate<T> – IntPredicate boolean test(T t) boolean test(int t)
  • 53. 53 Specialized Collectors Methods ● Average ● Summerizing ● Summing Collector<T, ?, Double> averagingInt(ToIntFunction<? super T> mapper) Collector<T, ?, IntSummaryStatistics> summerizingInt(ToIntFunction<? super T> mapper) Collector<T, ?, Integer> summingInt(ToIntFunction<? super T> mapper)
  • 56. 56 Parallelism ● If we limit ourselves to this restricted programming style, then we can (almost) get parallelism for free. ● Call parallel() to convert a stream to parallel stream.
  • 57. 57 Parallelism Example public class ParallelExample { public static long sumSeq(long[] array) { return Arrays.stream(array).sum(); } public static long sumPar(long[] array) { return Arrays.stream(array).parallel().sum(); } public static void main(String[] args) { int size = 40000000; long[] array = new long[size]; for (int i = 0; i < size; ++i) array[i] = i; long startSeq = System.nanoTime(); long resSeq = sumSeq(array); long durationSeq = System.nanoTime() - startSeq; long startPar = System.nanoTime(); long resPar = sumPar(array); long durationPar = System.nanoTime() - startPar; } } Output resultSeq: 799999980000000 resultPar: 799999980000000 durationSeq: 58598502 durationPar: 21206305
  • 60. 60 How to Receive Lambdas? ● The closure object is an object that can be passed around. ● The closure class will implement the specified interface. ● To run the body of the lambda expression, invoke the corresponding method. ● The interface should contain exactly one non-default abstract method. – Because we can choose arbitrary method name.
  • 61. 61 Functional Interfaces ● Interfaces with one non-default method. ● It is suggested to annotate with: @FunctionalInterface. @FunctionalInterface public interface MouseEventListener { public void accept(MouseEvent evt); } panel.registerListener( evt -> System.out.println("Processed!"));
  • 62. 62 Functional Interfaces import java.util.HashSet; public class Panel { private HashSet<MouseEventListener> listeners = new HashSet<MouseEventListener>(); public void registerListener(MouseEventListener cb) { listeners.add(cb); } public void notifyListener(MouseEvent evt) { listeners.forEach(x -> x.accept(evt)); } }
  • 63. 63 Default Method ● Problem: The language designer would like to add functions to interfaces, but it will break the existing program. ● Solution: We can specify the default method in an interface. – Default methods should only use other abstract methods, i.e. no field access is allowed.
  • 64. 64 Default Method ● Default methods will be inherited (and may be overrided) when the interface is extended. ● The closest default method will be chosen. ● To invoke the super default method, use the super keyword. ● It is necessary to override one if there are conflicts.
  • 65. 65 Static Method ● In Java 8, we can write static methods in interfaces as well. ● For example, Stream.of() is a notable static method in the interface.