1. lambda表達式介紹
lambda表達式是Java8提供的新特性之一,也可以稱之為閉包;它支持Java能夠進行簡單的函數(shù)式編程
,也就是說可以把一個匿名函數(shù)作為一個方法的參數(shù)進行傳遞;其格式分為三部分,第一部分為入?yún)⒘斜?,第二部?code>->固定組成,第三部分為方法體;
public class LambdaTest {
public static void main(String[] args) {
// 使用lambda表達式創(chuàng)建線程
Thread thread = new Thread(() -> {
System.out.println("thread running");
});
thread.start();
}
}
// 運行結(jié)果
thread running
2. lambda表達式的重要特征
可選的參數(shù)類型聲明:不需要聲明參數(shù)的類型,編譯器可以統(tǒng)一識別參數(shù)值;
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);
// 聲明參數(shù)類型
System.out.println("聲明參數(shù)類型");
lambdaTest.print((Integer a) -> {
System.out.println("a: " + a);
});
// 不聲明參數(shù)類型
System.out.println("不聲明參數(shù)類型");
lambdaTest.print((a) -> {
System.out.println("a: " + a);
});
}
}
interface LambdaInterface {
void print(Integer a);
}
// 運行結(jié)果
聲明參數(shù)類型
a: 123
不聲明參數(shù)類型
a: 123
可選的參數(shù)圓括號:一個參數(shù)時不需要定義圓括號,但沒有參數(shù)或者多個參數(shù)時則必須要定義;
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);
// 定義參數(shù)圓括號
System.out.println("定義參數(shù)圓括號");
lambdaTest.print((a) -> {
System.out.println("a: " + a);
});
// 一個參數(shù)可不定義參數(shù)圓括號
System.out.println("一個參數(shù)可不定義參數(shù)圓括號");
lambdaTest.print(a -> {
System.out.println("a: " + a);
});
}
}
interface LambdaInterface {
void print(Integer a);
}
// 運行結(jié)果
定義參數(shù)圓括號
a: 123
一個參數(shù)可不定義參數(shù)圓括號
a: 123
可選的大括號:如果方法體僅有一個語句,可不需要使用大括號;
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);
}
// 運行結(jié)果
使用方法體大括號
a: 123
一個語句可不使用方法體大括號
a: 123
可選的返回關(guān)鍵字:如果方法體僅有一個表達式返回值語句,可不需要聲明返回關(guān)鍵字,但存在大括號時則必須聲明;
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);
// 聲明返回關(guān)鍵字
System.out.println("聲明返回關(guān)鍵字");
Integer s1 = lambdaTest.sum((Integer a, Integer b) -> {
return a + b;
});
System.out.println(s1);
// 一個表達式返回值語句可不聲明返回關(guān)鍵字
System.out.println("一個表達式返回值語句可不聲明返回關(guān)鍵字");
Integer s2 = lambdaTest.sum((a, b) -> a + b);
System.out.println(s2);
}
}
interface LambdaInterface {
Integer calculate(Integer a, Integer b);
}
// 運行結(jié)果
聲明返回關(guān)鍵字
579
一個表達式返回值語句可不聲明返回關(guān)鍵字
579
3. lambda表達式對域外變量的限制
lambda表達式對域外的局部變量具有隱性final語義的限制,但對成員變量沒有該限制;
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) -> {
// 修改域外局部變量將出現(xiàn)編譯錯誤
c = 222;
return a + b;
});
System.out.println(s1);
int d = 333;
Integer s2 = lambdaTest.sum((a, b) -> {
// 域外修改lambda表達式內(nèi)部使用過的域外局部變量也將導(dǎo)致編譯錯誤
return a + b + d;
});
d = 444;
System.out.println(s2);
}
}
interface LambdaInterface {
Integer calculate(Integer a, Integer b);
}
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) -> {
// 沒有出現(xiàn)編譯錯誤
lambdaTest.c = 999;
return a + b + lambdaTest.c;
});
System.out.println(s1);
}
}
interface LambdaInterface {
Integer calculate(Integer a, Integer b);
}
// 運行結(jié)果
1578
4. lambda表達式的優(yōu)缺點
優(yōu)點:
1.使代碼更加簡潔;
2.減少匿名內(nèi)部類的創(chuàng)建,節(jié)省資源;
缺點:
1.可維護性差,必須熟悉抽象方法的參數(shù)列表;
2.可讀性差,必須對lambda表達式有一定深入;
5. lambda表達式的使用場景
在聲明方法時,方法的形參列表包含一個或者多個函數(shù)式接口就可以使用lambda表達式;如:
使用實現(xiàn)Runnable接口創(chuàng)建線程
使用實現(xiàn)Callable接口創(chuàng)建FutureTask
使用四大函數(shù)式接口消費者接口Consumer
、提供者接口Supplier
、斷言型接口Predicate
、函數(shù)型接口Function
6. lambda表達式的實現(xiàn)原理
lambda表達式是通過特定的語法,讓編譯器對java文件進行編譯時,針對每一個lambda表達式會編譯成一個對應(yīng)的靜態(tài)方法,由此也可證明lambda表達式并不是一種語法糖;
// 對上面的LambdaTest.java編譯后的LambdaTest.class文件使用javap -p進行查看將會得到如下結(jié)果
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);
}
到此這篇關(guān)于 Java 8 新特性 lambda 表達式詳細內(nèi)容總結(jié)的文章就介紹到這了,想要了解更多相關(guān) Java 其他新特性的內(nèi)容請搜索W3Cschool以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,也希望大家以后多多支持!