一、 Lambda 表達式概述
Lambda 表達式是 JDK8 的一個新特性,可以取代大部分的匿名內(nèi)部類,寫出更優(yōu)雅的 Java 代碼,尤其在集合的遍歷和其他集合操作中,可以極大地優(yōu)化代碼結(jié)構(gòu)。JDK 也提供了大量的內(nèi)置函數(shù)式接口供我們使用,使得 Lambda 表達式的運用更加方便、高效。
二、Lambda 格式
lambda 表達式的語法格式如下:
(parameters) -> expression
或
(parameters) ->{ statements; }
格式說明:
- 小括號內(nèi)的語法與傳統(tǒng)方法參數(shù)列表一致:無參數(shù)則留空;多個參數(shù)則用逗號分隔。
- -> 是新引入的語法格式,代表指向動作。
- 大括號內(nèi)的語法與傳統(tǒng)方法體要求基本一致。
重要特征:
- 可選類型聲明:不需要聲明參數(shù)類型,編譯器可以統(tǒng)一識別參數(shù)值。
- 可選的參數(shù)圓括號:一個參數(shù)無需定義圓括號,但多個參數(shù)需要定義圓括號。
- 可選的大括號:如果主體包含了一個語句,就不需要使用大括號。
- 可選的返回關鍵字:如果主體只有一個表達式返回值則編譯器會自動返回值,大括號需要指定明表達式返回了一個數(shù)值。
對接口的要求:
雖然使用 Lambda 表達式可以對某些接口進行簡單的實現(xiàn),但并不是所有的接口都可以使用 Lambda 表達式來實現(xiàn)。Lambda 規(guī)定接口中只能有一個需要被實現(xiàn)的方法,不是規(guī)定接口中只能有一個方法
jdk 8 中有另一個新特性:default, 被 default 修飾的方法會有默認實現(xiàn),不是必須被實現(xiàn)的方法,所以不影響 Lambda 表達式的使用。
@FunctionalInterface
修飾函數(shù)式接口的,要求接口中的抽象方法只有一個。 這個注解往往會和 lambda 表達式一起出現(xiàn)。下面給出四個接口來展示基礎語法,后文的全部操作都利用這四個接口來進行闡述。
案例代碼:
//定義四個接口
/**第一個接口:無參無返回值*/
@FunctionalInterface
public interface NoReturnNoParam {
void method();
}
/**第二個接口:一個參數(shù)無返回*/
@FunctionalInterface
public interface NoReturnOneParam {
void method(int a);
}
/**第三個接口:一個參數(shù)有返回值*/
@FunctionalInterface
public interface ReturnOneParam {
int method(int a);
}
/**第四個接口:多參數(shù)無返回*/
@FunctionalInterface
public interface NoReturnMultiParam {
void method(int a, int b);
}
//測試代碼
public static void main(String[] args) {
//第一個接口的測試
NoReturnNoParam noReturnNoParam = () -> {
System.out.println("第一個接口的測試結(jié)果:我是沒有參數(shù)沒有返回值的");
};
noReturnNoParam.method();
//第二個接口的測試
NoReturnOneParam noReturnOneParam = (int a) -> {
System.out.println("第二個接口的測試結(jié)果:一個參數(shù)沒有返回值 參數(shù)是:" + a);
};
noReturnOneParam.method(6);
//第三個接口的測試
ReturnOneParam returnOneParam = (int a) -> {
return a+1; //參數(shù)加1
};
int res2 = returnOneParam.method(6);//res2的值是7
System.out.println("第三個接口的測試結(jié)果:返回值:" + res2);
//第四個接口的測試
NoReturnMultiParam noReturnMultiParam = (int a, int b) -> {
System.out.println("第四個接口的測試結(jié)果:兩個參數(shù)沒有返回值 參數(shù)是:" + a +"," + b);
};
noReturnMultiParam.method(6, 8);
}
三、 Lambda 省略格式
我們可以通過觀察以下代碼來完成代碼的進一步簡化,寫出更加優(yōu)雅的代碼。
案例代碼:
public static void main(String[] args) {
//1.簡化參數(shù)小括號,如果只有一個參數(shù)則可以省略參數(shù)小括號
NoReturnOneParam lambda1 = a -> {
System.out.println("簡化參數(shù)小括號");
};
lambda1.method(1);
//2.簡化參數(shù)類型,可以不寫參數(shù)類型,但是必須所有參數(shù)都不寫
NoReturnMultiParam lamdba2 = (a, b) -> {
System.out.println("簡化參數(shù)類型");
};
lamdba2.method(1, 2);
//3.簡化方法體大括號,如果方法條只有一條語句,則可以省略方法體大括號
NoReturnNoParam lambda3 = () -> System.out.println("簡化方法體大括號");
lambda3.method();
//4.如果方法體只有一條語句,并且是 return 語句,則可以省略方法體大括號
ReturnOneParam lambda4 = a -> a+3;
System.out.println(lambda4.method(5));
}
四、 Lambda 常用示例
lambda 表達式創(chuàng)建線程:
public static void main(String[] args) {
//創(chuàng)建線程,通過匿名內(nèi)部類實現(xiàn)
/* new Thread(){
@Override
public void run() {
for (int i = 1; i <5 ; i++) {
System.out.print(i+" ");
}
}
}.start();*/
//lamdba表達式實現(xiàn)上邊線程創(chuàng)建
new Thread(()->{
for (int i = 1; i <5 ; i++) {
System.out.print(i+" ");
}
}).start();
}
lambda 表達式遍歷數(shù)字集合:
public static void main(String[] args) {
//ArrayList添加整數(shù)
ArrayList<Integer> list=new ArrayList<>();
list.add(10);
list.add(20);
list.add(30);
//遍歷
for(Integer num:list){
System.out.print(num+" ");
}
System.out.println();
//通過lambda表達遍歷集合
list.forEach(e->{
System.out.print(e+" ");
});
System.out.println();
//遍歷
list.forEach(System.out::println);
}
lambda 表達式從集合中刪除學生對象:
//學生類
public class Person {
private int id;
private String name;
public Person(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name +
'}';
}
}
//實現(xiàn)代碼
public static void main(String[] args) {
//創(chuàng)建集合
ArrayList<Person> list=new ArrayList<>();
list.add(new Person(1,"唐僧"));
list.add(new Person(2,"孫悟空"));
list.add(new Person(3,"豬八戒"));
list.add(new Person(4,"沙僧"));
//刪除姓名是ls人從集合中
/* for(int i=0;i<list.size();i++){
if("豬八戒".equals(list.get(i).getName())){
list.remove(i);
}
}*/
list.removeIf(e-> "豬八戒".equals(e.getName()));
list.forEach(System.out::println);
}
五、Lambda 注意事項
- 使用Lambda必須要有接口,并且要求接口中有且僅有一個抽象方法
- 表達式的參數(shù)類型可以省略,且必須同時省略,或都不省略,不能只省略一個而其他的不省略。如(int a, int b)可以寫成 :(a, b)->{...}。
- 如果只有一個參數(shù),Lambda表達式的(parameter)可以省略括號直接寫參數(shù):parameter。
- 如果{...}代碼塊的語句只有一條,(1)可以省略大括號和分號: parameter -> 方法體... 。(2)如果{...}代碼塊里面有返回值,需要return result ,return也要省略:parameter -> result