-
Notifications
You must be signed in to change notification settings - Fork 48
Lambda Expression
Lambda expression is also called anonymous function, usually contain 4 parts:
- Code block
- Expression parameters
- Internal variables
- External variables
Example of a lambda expression: x -> x + n. The first x is the argument taken in. It does not necessarily be x! It could be y ,z, potato.. anything! Moving on to the -> x + n. The inner x would refer to a bounded variable whereas n will be a free variable.
Function<Integer, Integer> addN(int n /* final External variable */) {
/* Code block */
/* Step3 and Step4 */
Function<Integer,Integer> result /* Internal variable */ = x /* Expression parameter */ -> x + n;
/* Step5 */
return result;
}
Function<Integer, Integer> add5 /* Step1 */ = addN(5 /* Step2 */);
/* Step6 */
add5.apply(7);
/* Output */
12
- Lambda expression is a closure. The internal and external variables will be copied from the stack into a closure object (in the heap). If the closure object is executed asynchronously, even if the internal and external variables are released in the
main()
thread, the variables can still be accessed in the Lambda expression - Since updating ecternal variables in lambda expressions is not thread safe, external variable must be final or effectively final (compiler will flag error if they are changed)
- final is easier to understand, but how to understand effectively final? In the following example, List is a valid final variable. But the problem is that List is a mutable object. If the following method is called by multiple threads, concurrency issue will happen.
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
Function<Integer, Integer> function = (x) -> {
list.add(x); /* list is effectively final variable */
return x;
};
for (int i = 0; i < 10; i++) {
final int x = i;
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(x * new Random().nextInt(100));
} catch (Exception e) {
}
function.apply(x);
System.out.println(list);
}
});
t.start();
}
}
/* Output */
[0]
[0, 4]
[0, 4, 7]
[0, 4, 7, 1]
[0, 4, 7, 1, 2]
[0, 4, 7, 1, 2, 8]
[0, 4, 7, 1, 2, 8, 3]
[0, 4, 7, 1, 2, 8, 3, 9]
[0, 4, 7, 1, 2, 8, 3, 9, 5]
[0, 4, 7, 1, 2, 8, 3, 9, 5, 6]
- Performance optimization
- Easy to write
public class Lambda {
public static void showLog(int level, String message) {
if (level == 1) {
System.out.println(message);
}
}
public static void main(String[] args) {
String message1 = "Hello";
String message2 = "World";
showLog(1, message1 + message2);
}
}
Before calling the showLog method, message1 and message2 will be concatenated together. If level is 1, Hello World will be displayed. If level is not 1, there will be no output. At this time, the concatenation operation of message1 and message2 is wasteful.
@FunctionalInterface
public interface ILambda {
String concatMessage();
}
public class Lambda {
public static void showLog(int level, ILambda message) {
if (level == 1) {
System.out.println(message.concatMessage());
}
}
public static void main(String[] args) {
String message1 = "Hello";
String message2 = "World";
// Lambda expression
showLog(1, () -> {
return message1 + message2;
});
}
}
With the Lambda expression, if the level is 1, the concatMessage method in the interface ILambda will be called, and then the string will be concatenated together. Otherwise, the concatMessage method in the interface ILambda will not be called, and the string will not be concatenated together. Therefore, Lambda expression can optimize the program to a certain extent.
Peer Learning
Codecrunch Contributions
Piazza Contributions
Wiki Contributions
Guides
Setting Up Checkstyle
Setting Up Java
Setting Up MacVim
Setting Up Sunfire
Setting Up Unix For Mac
Setting Up Unix For Windows
Setting Up Vim
Setting up SSH Config
CS2030 Contents
Lecture 1 SummaryCompile-run vs Run-time Summary
Quick Guide To Abstraction
Generics and Variance of Types
Comparable vs Comparator
Summary of completable future
CS2030S Notes
ELI5 Optional.map vs Optional.flatMap
PECS Example Code
Java Collection Framework (Iterator)
Generic
Generic Type Parameter and Generic Wildcard
Calculator
Lambda-Expression
Single Abstract Method (SAM)
Method Reference
Functional Interfaces 2
Simple Usage of Sandbox
Associative-but-not-commutative
Higher Order function
Functional Programming
Calculator With Functor
Eager Evaluation VS Lazy Evaluation
Simple Usage of Lazy Evaluation
Lazy Evaluation for LazyList
Lazy Evaluation for BinaryTree
Stream
Parallel Stream
Optional
Simple Usage of Stream
Asynchronous Programming
Notes on CompletableFuture
Notes on CompletableFuture 2
Simple Usage of CompletableFuture
Mind Map
Exception Handling
Links
CS2030 Java Style Guide
CS2030 Javadoc Specification
JDK 11 Download Link
JDK 11 API Docs
Codecrunch
Piazza Forum