1. lambda表達式介紹
lambda表達式是Java8提供的新特性之一,也可以稱之為閉包;它支持Java能夠進行簡單的函數式編程
,也就是說可以把一個匿名函數作為一個方法的參數進行傳遞;其格式分為三部分,第一部分為入參列表,第二部由->
固定組成,第三部分為方法體;
1
2
3
4
5
6
7
8
9
10
|
public class LambdaTest { public static void main(String[] args) { // 使用lambda表達式創建線程 Thread thread = new Thread(() -> { System.out.println( "thread running" ); }); thread.start(); } } |
// 運行結果
thread running
2. lambda表達式的重要特征
可選的參數類型聲明:不需要聲明參數的類型,編譯器可以統一識別參數值;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
public class LambdaTest { private Integer a; public LambdaTest(Integer a) { this .a = a; } public void print(LambdaInterface lambdaInterface) { lambdaInterface.print( this .a); } public static void main(String[] args) { LambdaTest lambdaTest = new LambdaTest( 123 ); // 聲明參數類型 System.out.println( "聲明參數類型" ); lambdaTest.print((Integer a) -> { System.out.println( "a: " + a); }); // 不聲明參數類型 System.out.println( "不聲明參數類型" ); lambdaTest.print((a) -> { System.out.println( "a: " + a); }); } } interface LambdaInterface { void print(Integer a); } |
// 運行結果
聲明參數類型
a: 123
不聲明參數類型
a: 123
可選的參數圓括號:一個參數時不需要定義圓括號,但沒有參數或者多個參數時則必須要定義;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
public class LambdaTest { private Integer a; public LambdaTest(Integer a) { this .a = a; } public void print(LambdaInterface lambdaInterface) { lambdaInterface.print( this .a); } public static void main(String[] args) { LambdaTest lambdaTest = new LambdaTest( 123 ); // 定義參數圓括號 System.out.println( "定義參數圓括號" ); lambdaTest.print((a) -> { System.out.println( "a: " + a); }); // 一個參數可不定義參數圓括號 System.out.println( "一個參數可不定義參數圓括號" ); lambdaTest.print(a -> { System.out.println( "a: " + a); }); } } interface LambdaInterface { void print(Integer a); } |
// 運行結果
定義參數圓括號
a: 123
一個參數可不定義參數圓括號
a: 123
可選的大括號:如果方法體僅有一個語句,可不需要使用大括號;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
public class LambdaTest { private Integer a; public LambdaTest(Integer a) { this .a = a; } public void print(LambdaInterface lambdaInterface) { lambdaInterface.print( this .a); } public static void main(String[] args) { LambdaTest lambdaTest = new LambdaTest( 123 ); // 使用方法體大括號 System.out.println( "使用方法體大括號" ); lambdaTest.print(a -> { System.out.println( "a: " + a); }); // 一個語句可不使用方法體大括號 System.out.println( "一個語句可不使用方法體大括號" ); lambdaTest.print(a -> System.out.println( "a: " + a)); } } interface LambdaInterface { void print(Integer a); } |
// 運行結果
使用方法體大括號
a: 123
一個語句可不使用方法體大括號
a: 123
可選的返回關鍵字:如果方法體僅有一個表達式返回值語句,可不需要聲明返回關鍵字,但存在大括號時則必須聲明;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public class LambdaTest { private Integer a; private Integer b; public LambdaTest(Integer a, Integer b) { this .a = a; this .b = b; } public Integer sum(LambdaInterface lambdaInterface) { return lambdaInterface.calculate( this .a, this .b); } public static void main(String[] args) { LambdaTest lambdaTest = new LambdaTest( 123 , 456 ); // 聲明返回關鍵字 System.out.println( "聲明返回關鍵字" ); Integer s1 = lambdaTest.sum((Integer a, Integer b) -> { return a + b; }); System.out.println(s1); // 一個表達式返回值語句可不聲明返回關鍵字 System.out.println( "一個表達式返回值語句可不聲明返回關鍵字" ); Integer s2 = lambdaTest.sum((a, b) -> a + b); System.out.println(s2); } } interface LambdaInterface { Integer calculate(Integer a, Integer b); } |
// 運行結果
聲明返回關鍵字
579
一個表達式返回值語句可不聲明返回關鍵字
579
3. lambda表達式對域外變量的限制
lambda表達式對域外的局部變量具有隱性final語義的限制,但對成員變量沒有該限制;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
public class LambdaTest { private Integer a; private Integer b; public LambdaTest(Integer a, Integer b) { this .a = a; this .b = b; } public Integer sum(LambdaInterface lambdaInterface) { return lambdaInterface.calculate( this .a, this .b); } public static void main(String[] args) { LambdaTest lambdaTest = new LambdaTest( 123 , 456 ); int c = 111 ; Integer s1 = lambdaTest.sum((a, b) -> { // 修改域外局部變量將出現編譯錯誤 c = 222 ; return a + b; }); System.out.println(s1); int d = 333 ; Integer s2 = lambdaTest.sum((a, b) -> { // 域外修改lambda表達式內部使用過的域外局部變量也將導致編譯錯誤 return a + b + d; }); d = 444 ; System.out.println(s2); } } interface LambdaInterface { Integer calculate(Integer a, Integer b); } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
public class LambdaTest { private Integer a; private Integer b; private Integer c; public LambdaTest(Integer a, Integer b, Integer c) { this .a = a; this .b = b; this .c = c; } public Integer sum(LambdaInterface lambdaInterface) { return lambdaInterface.calculate( this .a, this .b); } public static void main(String[] args) { LambdaTest lambdaTest = new LambdaTest( 123 , 456 , 789 ); Integer s1 = lambdaTest.sum((a, b) -> { // 沒有出現編譯錯誤 lambdaTest.c = 999 ; return a + b + lambdaTest.c; }); System.out.println(s1); } } interface LambdaInterface { Integer calculate(Integer a, Integer b); } |
// 運行結果
1578
4. lambda表達式的優缺點
優點:
1.使代碼更加簡潔;
2.減少匿名內部類的創建,節省資源;
缺點:
1.可維護性差,必須熟悉抽象方法的參數列表;
2.可讀性差,必須對lambda表達式有一定深入;
5. lambda表達式的使用場景
在聲明方法時,方法的形參列表包含一個或者多個函數式接口就可以使用lambda表達式;如:
使用實現Runnable接口創建線程
使用實現Callable接口創建FutureTask
使用四大函數式接口消費者接口Consumer
、提供者接口Supplier
、斷言型接口Predicate
、函數型接口Function
6. lambda表達式的實現原理
lambda表達式是通過特定的語法,讓編譯器對java文件進行編譯時,針對每一個lambda表達式會編譯成一個對應的靜態方法,由此也可證明lambda表達式并不是一種語法糖;
1
2
3
4
5
6
7
8
9
10
11
12
|
// 對上面的LambdaTest.java編譯后的LambdaTest.class文件使用javap -p進行查看將會得到如下結果 javap -p LambdaTest. class Compiled from "LambdaTest.java" public class cn.jackiegu.java8.study.lambda.LambdaTest { private java.lang.Integer a; private java.lang.Integer b; private java.lang.Integer c; public cn.jackiegu.java8.study.lambda.LambdaTest(java.lang.Integer, java.lang.Integer, java.lang.Integer); public java.lang.Integer sum(cn.jackiegu.java8.study.lambda.LambdaInterface); public static void main(java.lang.String[]); private static java.lang.Integer lambda$main$ 0 (cn.jackiegu.java8.study.lambda.LambdaTest, java.lang.Integer, java.lang.Integer); } |
到此這篇關于Java8新特性之Lambda表達式的使用的文章就介紹到這了,更多相關java的Lambda表達式內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/gu19930914/article/details/115694182