0% found this document useful (0 votes)
61 views48 pages

Lambdas

The document discusses lambda expressions, behavior parameterization, and streams in Java. It covers lambda syntax and how they can be used to pass functions as arguments. It also discusses Java's functional interfaces and how streams provide a declarative and composable way to process data sequentially and in parallel.

Uploaded by

victorw63
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
61 views48 pages

Lambdas

The document discusses lambda expressions, behavior parameterization, and streams in Java. It covers lambda syntax and how they can be used to pass functions as arguments. It also discusses Java's functional interfaces and how streams provide a declarative and composable way to process data sequentially and in parallel.

Uploaded by

victorw63
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 48

Advanced Java Programming

51037
Adam Gerber, PhD, SCJP
[email protected]
Lecture 02 Agenda:

1/ Behavior Parameterization and Lambda expressions


2/ The java.util.function.* library
3/ Streams

2
Lambda Function

• Functions are now first-class citizens


• Store a method in a Lambda for deferred execution.
• Lambdas are not objects (reflection and “this” do not
3
work
Behavior Parameterization

What is the problem with a “STRICTLY” object-oriented


programming language? Everything is either a primitive or an
object.

What's good about the OO paradigm?

+ OO is extremely powerful. It affords inheritence,


polymorphism, and reflection….however...
+ Strict OO forces you to think in terms of Objects living on the
heap and your code is highly imperative (branching and
explicit looping).

+ OO was a great leap forward from procedural programming.


+ OO is not going to be replaced any time soon. It's way too
powerful. Rather it will live alongside functional programming.

4
How did Java deal with “functional”
programming prior to Java8. Anon
(inner) classes!

Urma/behaviorParam/_01TheProblemDefined
Another example of anon class
Our first Lambda expression
Our first Lambda expression

1/ start with a “functional interface” - a functional interface


has ONE non-default abstract method.
2/ create an anonymous class and implement its method
3/ use the format as seen above
4/ no need for return statements, that's implied
Another example
Urma/behaviorParam/_02BehaviorP1 and P3
Another example

Urma/behaviorParam/_02BehaviorP4
The “Type” of Lambda Expression
• The java ‘Type’ of a lamba expression is a “Functional
Interface”
• Functional Interface is an interface with exactly ONE
non-default, non-overriding method.
• A Lambda can NOT use reflection as it is NOT an
object.
• A lambda can not use the “this” keyword as it is NOT
an object.
• Much like instance methods, a lambda does not live
on the heap.
Location of Functional Interfaces
• You may define your own “Functional
Interfaces”
• Java8 defines many in: java.util.function.*
• 43 interfaces in 4 categories, such as Function,
Supplier, Consumer, Predicate.

Urma/behaviorParam/PrimableDriver.java
Can I store a Lamba Expression in
a variable in Java?
• Yes!
• Wherever a method requires an
anonymous inner class (with one method),
you may put a lamba expression.
• For example: Collections.sort(list, compL);
• You may also use lambda expressions
with Streams
Is a Lambda expression an Object?
• Not really. It is an ‘object without identity’.
• It does not inherit from Object and so you
can’t call the .equals(), .hashcode(), etc.
• There is no ‘new’ keyword in lamba, so
there is far less overhead both at compile-
and run-time.
• You can't use 'this' keyword to identify it
using reflection.
Syntax of Java 8 Lambdas
• A Java 8 lambda is basically a method in Java without a declaration usually written
as (parameters) -> { body }. Examples,

1. (int x, int y) -> { return x + y; }

2. x -> x * x

3. ( ) -> x

• A lambda can have zero or more parameters separated by commas and their type
can be explicitly declared or inferred from the context.

• Parenthesis are not needed around a single parameter.

• ( ) is used to denote zero parameters.

• The body can contain zero or more statements.

• Braces are not needed around a single-statement body. 15


What is Functional Programming?
• A style of programming that treats computation as
the evaluation of mathematical functions
• Eliminates side effects
• Treats data as being immutable
• Expressions have referential transparency – this
reference will do this and this only.
• Functions can take functions as arguments and
return functions as results
• Prefers recursion over explicit for-loops 16
Why do Functional Programming?

• Allows us to write easier-to-understand, more


declarative, more concise programs than
imperative programming
• Allows us to focus on the problem rather than
the code
• Facilitates parallelism

17
Example 1:
Print a list of integers with a lambda

List<Integer> intSeq = Arrays.asList(1,2,3);

intSeq.forEach(x -> System.out.println(x));

• x -> System.out.println(x) is a lambda expression that


defines an anonymous function with one parameter
named x of type Integer
18
Example 2:
A multiline lambda
List<Integer> intSeq = Arrays.asList(1,2,3);

intSeq.forEach(x -> {

x += 2;

System.out.println(x);

});

• Braces are needed to enclose a multiline body in a lambda


expression. 19
Example 3:
A lambda with a defined local variable
List<Integer> intSeq = Arrays.asList(1,2,3);

intSeq.forEach(x -> {

int y = x * 2;

System.out.println(y);

});

• Just as with ordinary functions, you can define local


variables inside the body of a lambda expression
20
Example 4:
A lambda with a declared parameter type
List<Integer> intSeq = Arrays.asList(1,2,3);

intSeq.forEach((Integer x -> {

x += 2;

System.out.println(x);

});

• You can, if you wish, specify the parameter type.


21
The java.util.function.* library

Functional Interfaces:
Examine the SDK java.util.function

Consumers
Predicates
Suppliers
Functions
Numeric Performance Functional Interfaces
Operators

Urma/behaviorParam/UsingConsumers.java

22
4 categories of Functional
Interfaces
Functional Interface Example used in
archetypes
Consumer forEach(Consumer),
peek(Consumer)
Predicate filter(Predicate)
Function map(Function)
Supplier reduce(Supplier)
collect(Supplier)

See java.util.function.*
ConsumerMain

23
Functional Interfaces
• Design decision: Java 8 lambdas are assigned to functional
interfaces.

• A functional interface is a Java interface with exactly one non-


default method. E.g.,
public interface Consumer<T> {
void accept(T t);
}

• The package java.util.function defines many new


useful functional interfaces. 24
Implementation of Java 8 Lambdas

• The Java 8 compiler first converts a lambda expression into a


function

• It then calls the generated function

• For example, x -> System.out.println(x) could be


converted into a generated static function
public static void genName(Integer x) {
System.out.println(x);
}

25
Variable Capture

• Lambdas can interact with variables defined


outside the body of the lambda

• Using these variables is called variable capture


• These variables must be effectively final.

26
Local Variable Capture Example

public class LVCExample {

public static void main(String[] args) {

List<Integer> intSeq = Arrays.asList(1,2,3);

int var = 10;

intSeq.forEach(x -> System.out.println(x + var));

}
Urma/_var_capture/

27
Static Variable Capture Example

public class SVCExample {

private static int var = 10;

public static void main(String[] args) {

List<Integer> intSeq = Arrays.asList(1,2,3);

intSeq.forEach(x -> System.out.println(x + var));

28
Method References

• Method references can be used to pass an


existing function in places where a lambda is
expected
• The signature of the referenced method needs
to match the signature of the functional
interface method

29
Conciseness with Method
References
We can rewrite the statement

intSeq.forEach(x -> System.out.println(x));

more concisely using a method reference

intSeq.forEach(System.out::println);
package urma._method_references;
30
Streams
Declarative— More concise and readable
Composable— Greater flexibility
Parallelizable— Better performance
What is a stream?
A stream is “a sequence of elements from a source that
supports data processing operations.” Internal
iteration.

Collections are held in memory space. You need the


entire collection to iterate. SPACE

Streams are created on-demand and they are infinite.


TIME
Streams are like Unix pipes

Locally - nav to /h/dev/java/adv/2015


$ cat a.txt b.txt | tr "[a-z]" "[A-Z]" | sort | tail -3

Peforrm from terminal or gitbash.


Typical operations

map(Dish::getName)
Examine the Collections Interface
Stream is defined in the collections interface. All
these new methods are grandfathered-in
starting with Java8 using default.
Streams are infinite
Streams are consumed

> Streams are consumed. You can iterate over


them only once.
> You can get a new stream from the initial
data source to traverse it again just like for an
iterator (assuming it’s a repeatable source like
a collection; if it’s an I/O channel,
you’re out of luck).

Urma/spent_iterator.
Intermediate versus Terminal ops

Only the terminal operation can consume the


stream which is done in a lazy manner – or on-
demand.
Example Intermediate Operations
• filter excludes all elements that don’t match
a Predicate.

• map performs a one-to-one transformation of


elements using a Function.
A Stream Pipeline
A stream pipeline has three components:
1.A source such as a Collection, an array, a
generator function, or an IO channel;
2.Zero or more intermediate operations; and
3.A terminal operation
Map is a transform operation

Takes a Stream<T> and returns a Stream<U>


Stream Example
int sum = widgets.stream()
.filter(w -> w.getColor() == RED)
.mapToInt(w -> w.getWeight())
.sum();

Here, widgets is a Collection<Widget>. We create a stream of


Widget objects via Collection.stream(), filter it to produce a
stream containing only the red widgets, and then transform it into a
stream of int values representing the weight of each red widget.
Then this stream is summed to produce a total weight.

From Java Docs


Interface Stream<T>
Parting Example: Using lambdas and stream to
sum the squares of the elements on a list

List<Integer> list = Arrays.asList(1,2,3);


int sum = list.stream().map(x -> x*x).reduce((x,y) -> x + y).get();
System.out.println(sum);

• Here map(x -> x*x) squares each element and


then reduce((x,y) -> x + y) reduces all elements
into a single number

http://viralpatel.net/blogs/lambda-expressions-java-tutorial/
Intermediary operation
• Intermediary operation: A method that
takes a Stream and returns a Stream.
• They are lazily loaded and will only be
executed if you include a terminal
operation at the end.
– The peek() method
– The map() method
– The filter() method
Terminal operation
• Terminal operation: A method that takes a
Stream<T> and returns void.
• They are eagerly loaded and will cause the
entire pipeline to be executed.
• A terminal operation will “spend” the stream.
– The forEach() method
– The count() method
– The max() method
– The collect() method
– The reduce() method
Stream Example
int sum = widgets.stream()

.filter(w -> w.getColor() == RED)

.mapToInt(w -> w.getWeight())

.sum();

Here, widgets is a Collection<Widget>. We create a stream of


Widget objects via Collection.stream(), filter it to produce a
stream containing only the red widgets, and then transform it into a
stream of int values representing the weight of each red widget.
From Java Docs
46Interface Stream<T>
Then this stream is summed to produce a total weight.
References
A lot of the material in this lecture is discussed in much more
detail in these informative references:

• The Java Tutorials,


http://docs.oracle.com/javase/tutorial/java/index.html

• Lambda Expressions,
http://docs.oracle.com/javase/tutorial/java/javaOO/lambdae
xpressions.html

• Adib Saikali, Java 8 Lambda Expressions and Streams,


www.youtube.com/watch?v=8pDm_kH4YKY

• Brian Goetz, Lambdas in Java: A peek under the hood.


https://www.youtube.com/watch?v=MLksirK9nnE 47
References
A lot of the material in this lecture is discussed in much more
detail in these informative references:

• The Java Tutorials,


http://docs.oracle.com/javase/tutorial/java/index.html
• Lambda Expressions,
http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaex
pressions.html
• Adib Saikali, Java 8 Lambda Expressions and Streams,
www.youtube.com/watch?v=8pDm_kH4YKY
• Brian Goetz, Lambdas in Java: A peek under the hood.
https://www.youtube.com/watch?v=MLksirK9nnE

You might also like