Article directory
1 Introduction
- Lambda expressions are an important new feature in Java SE8
- Lambda expressions allow you to replace functional interfaces with expressions
- Lambda expressions, like methods, provide a normal parameter list and a body that uses those parameters
- Lambda expression can be thought of as an anonymous function, named after the λ calculus in mathematics, it can also be called a closure
- Lambda expressions allow a function to be used as a method parameter
2. Syntax of Lambda Expressions
Basic form: Lambda expression consists of three parts: parameter, -> symbol, method body
(参数列表)->{
方法体}
Replenish:
- Lambda expressions can have zero or more parameters
- The type of the parameter can be explicitly declared or not, and it is implicitly inferred by the JVM. For example,
(int a)
and(a)
have the same effect- When there is only one parameter and the type can be deduced, parentheses can be omitted, for example,
(a)
the samea
effect as- If the method body of the lambda expression has only one statement, the curly braces can be omitted
- If the method body of the lambda expression has only one statement and is the return value, you can omit return
Code example:
// 不需要参数,返回值为 2
()->2
// 接收一个参数(数字类型),返回值为其2倍的值
x->2*x
// 接收两个参数(数字类型),并返回它们的和
(x,y)->x+y
// 接收两个 int 类型参数,返回它们的乘积
(int x,int y)->x*y
// 接收一个 String 对象,并在控制台打印
(String s)->System.out.println(s)
3. Function interface
ifAn interface has only one abstract method, and such an interface is called a single interface. Starting with JDK8, Java uses Lambda expressions and willA single interface is called a functional interface
Notice:
- An interface is a functional interface if it has only one abstract method
- If we declare an
@FunctionInterface
annotation , the compiler will require the interface according to the definition of the functional interface, so this interface can only have one abstract method. If it exceeds, the program will report an error when compiling
Sample code:
@functionInterface
interface A{
void test();
}
4. The use of Lamdba expressions
Next, we will demonstrate the use of lambda expressions
// 无返回值无参数
@FunctionalInterface interface NoParameterNoReturn {
void test(); }
// 无返回值一个参数
@FunctionalInterface interface OneParameterNoReturn {
void test(int a); }
// 无返回值多个参数
@FunctionalInterface interface MoreParameterNoReturn {
void test(int a,int b); }
// 有返回值无参数
@FunctionalInterface interface NoParameterReturn {
int test(); }
// 有返回值一个参数
@FunctionalInterface interface OneParameterReturn {
int test(int a); }
// 有返回值多参数
@FunctionalInterface interface MoreParameterReturn {
int test(int a,int b); }
public class TestDemo {
public static void main(String[] args) {
NoParameterNoReturn noParameterNoReturn = ()->{
System.out.println("无参数无返回值"); };
noParameterNoReturn.test();
OneParameterNoReturn oneParameterNoReturn = (int a)->{
System.out.println("无参数一个返回值:"+ a); };
oneParameterNoReturn.test(10);
MoreParameterNoReturn moreParameterNoReturn = (int a,int b)->{
System.out.println("无返回值多个参数:"+a+" "+b); };
moreParameterNoReturn.test(20,30);
NoParameterReturn noParameterReturn = ()->{
System.out.println("有返回值无参数!"); return 40; };
//接收函数的返回值
int ret = noParameterReturn.test();
System.out.println(ret);
OneParameterReturn oneParameterReturn = (int a)->{
System.out.println("有返回值有参数!"); return a; };
ret = oneParameterReturn.test(50);
System.out.println(ret);
MoreParameterReturn moreParameterReturn = (int a,int b)->{
System.out.println("有返回值多个参数!"); return a+b; };
ret = moreParameterReturn.test(60,70);
System.out.println(ret);
}
}
5. Variable capture
5.1 Introduction
Variable capture exists for both local and anonymous classes in Java
Only after we understand what variable capture is, we can better understand the scope of lambda expressions, because lambda expressions also have variable capture.
5.2 Variable capture of anonymous inner classes
class A {
public void func(){
System.out.println("func()");
}
}
public class TestDemo {
public static void main(String[] args) {
int a = 100;
new Test(){
@Override public void func() {
System.out.println("我是内部类,且重写了func这个方法!");
System.out.println("我是捕获到变量 a == "+a +" 我是一个常量,或者是一个没有改变过值的变量!");
}
};
}
}
The variable a in the above code is a captured variable. This variable is either modified by final, or it is necessary to ensure that the variable is not modified when used in an anonymous inner class. If modified, a compilation error will occur.
5.3 Lambda variable capture
Variable capture is also possible in Lambda
@FunctionalInterface interface A {
void test();
}
public static void main(String[] args) {
int a = 10;
NoParameterNoReturn noParameterNoReturn = ()->{
// a = 99; 如果修改a,则会报错
System.out.println("捕获变量:"+a);
};
noParameterNoReturn.test();
}
6. The use of Lambda in collections
In order to make Lambda and Java collection classes work better together, some new interfaces have been added to the collection for docking with Lambda expressions
corresponding interface | Added method |
---|---|
Collection | removeIf() 、spliterator() 、stream() 、parallelStream() 、forEach() |
List | replaceAll() 、sort() |
Map | getDefault() 、forEach() 、replaceAll() 、putIfAbsent() 、remove() 、replace() 、computeIfAbsent() 、computeIfPresent() 、compute() 、merge() |
Replenish:
Collection's
forEach()
methods arejava.lang.Interable
inherited from interface
6.1 Collection interface
Demonstration using the forEach() method
forEach()
Source code:
Code Example: Using Anonymous Inner Classes
public class TestDemo{
public static void main(String[] args) {
List<String> list=new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.print(s+" ");
}
});
}
}
// 结果为:aaa bbb ccc
Code Example: Using Lambda
public class TestDemo{
public static void main(String[] args) {
List<String> list=new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.forEach(s -> System.out.print(s+" "));
}
}
// 结果为:aaa bbb ccc
6.2 List interface
Demonstration using the sort() method
sort()
Source code:
Code Example: Using Anonymous Inner Classes
public class TestDemo{
public static void main(String[] args) {
List<String> list=new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.sort(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
System.out.println(list);
}
}
// 结果为:[aaa, bbb, ccc]
Code Example: Using Lambda
public class TestDemo{
public static void main(String[] args) {
List<String> list=new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.sort((String o1,String o2)->o1.compareTo(o2));
System.out.println(list);
}
}
// 结果为:[aaa, bbb, ccc]
6.3 Map interface
Demonstrate using the forEach() method of HashMap
HashMap 的 forEach()
Source code:
Code Example: Using Anonymous Inner Classes
public class TestDemo{
public static void main(String[] args) {
Map<Integer,String> map=new HashMap<>();
map.put(1,"aaa");
map.put(2,"222");
map.put(3,"333");
map.forEach(new BiConsumer<Integer, String>() {
@Override
public void accept(Integer integer, String s) {
System.out.println("Key="+integer+" Value="+s);
}
});
}
}
/** 结果为:
Key=1 Value=aaa
Key=2 Value=222
Key=3 Value=333
*/
Code Example: Using Lambda
public class TestDemo{
public static void main(String[] args) {
Map<Integer,String> map=new HashMap<>();
map.put(1,"aaa");
map.put(2,"222");
map.put(3,"333");
map.forEach((Integer integer,String s)->
System.out.println("Key="+integer+" Value="+s));
}
}
/** 结果为:
Key=1 Value=aaa
Key=2 Value=222
Key=3 Value=333
*/
7. Advantages and Disadvantages of Lambda Expressions
advantage:
- Simple code, rapid development
- Convenient functional programming
- Easy to parallelize
- Java introduces Lambda to improve collection operations
shortcoming:
- Poor code readability
- In non-parallel computing, many computations may not have the high performance of traditional for loops