文章目錄
- 一、Lambda運算式簡介
- 二、Lambda運算式語法
- 三、函式參考
- 1.靜態方法參考
- 2.非靜態方法參考
- 3.構造方法參考
- 4.物件方法的特殊參考
- 四、Lambda運算式需要注意的問題
一、Lambda運算式簡介
Lambda運算式,是Java8的一個新特性,也是Java8中最值得學習的新特性之一,(另一個新特性是流式編程,)
-
Lambda運算式,從本質上講是一個
匿名方法,可以使用這個匿名方法,實作介面中的方法, -
功能:通常使用Lambda運算式,是為了
簡化介面實作的,關于介面實作可以有多種方式實作,例如:①設計介面的實作類、②使用匿名內部類,但是③使用lambda運算式,比這兩種方式都簡單, -
要求:lambda運算式,
只能實作函式式介面:即一個介面中,要求實作類必須實作的抽象方法,有且只有一個,
@FunctionalInterface注解,用在介面之前,用來判斷介面是否是一個函式式介面,如果不是函式式介面會報錯,功能類似于@Override,
二、Lambda運算式語法
lambda運算式本質上是一個匿名方法,因此再寫lambda運算式時,不需要關心方法名是什么,也不需要關心回傳值型別,只需要關心兩部分:
引數串列、方法體,
- ()引數部分:方法的引數串列,要求和實作的介面中的方法引數部分一致,包括引數的數量和型別,
- {}方法體部分:方法的實作部分,如果介面中定義的方法有回傳值,則在實作時,注意回傳值的回傳,
- -> :分隔引數部分和方法體部分,
Lambda運算式基礎語法:
(引數) ->{
方法體
}
下面定義6種引數和回傳值各不相同的
函式式介面,分別使用lambda運算式對介面中的方法進行實作:

下面是針對上面6種函式式介面的lambda運算式實作,
/**
* @Description:
* @author Guoqianliang
* @date 19:50 - 2021/2/15
*/
public class BasicSyntax {
public static void main(String[] args) {
// 1.實作無引數,無回傳值的函式式介面
NoneReturnNoneParameter lambda1 = () -> {
System.out.println("這是無參,無回傳值的方法");
};
lambda1.test();
// 2.實作一個引數,無回傳值的函式式介面
NoneReturnSingleParameter lambda2 = (int a) -> {
System.out.println("這是一個引數,無回傳值的方法,引數a:" + a);
};
lambda2.test(10);
// 3.實作多個引數,無回傳值的函式式介面
NoneReturnMutipleParameter lambda3 = (int a, int b) -> {
System.out.println("這是多個引數,無回傳值的方法,引數a=" + a + ",b=" + b);
};
lambda3.test(10, 20);
// 4.實作無引數,有回傳值有回傳值的函式式介面
SingleReturnNoneParameter lambda4 = () -> {
System.out.println("這是無引數,有回傳值的方法,回傳值是:");
return 10;
};
System.out.println(lambda4.test());
// 5.實作一個引數,有回傳值的函式式介面
SingleReturnSingleParameter lambda5 = (int a) -> {
System.out.println("這是一個引數,有回傳值的方法,回傳值是:");
return a;
};
System.out.println(lambda5.test(10));
// 6.實作多個引數,有回傳值的函式式介面
SingleReturnMutipleParameter lambda6 = (int a, int b) -> {
System.out.println("這是多個引數,有回傳值的方法,回傳值是:");
return a + b;
};
System.out.println(lambda6.test(1, 2));
}
}
語法精簡進階:
- 引數串列的引數型別可以省略,
- 如果引數串列中的引數有且只有一個,可以省略小括號,
- 如果方法體中只有一條陳述句,可以省略大括號,(注:如果這條陳述句是回傳陳述句,省略了大括號后也要把return關鍵字省略)
三、函式參考
lambda運算式是為了簡化介面,在lambda運算式中,不應該出現比較復雜的邏輯,如果需要處理的邏輯比較復雜,一般情況會單獨寫一個方法,在lambda運算式中直接參考這個方法即可,即
參考一個已經存在的方法,使其代替lambda運算式完成介面的實作,
1.靜態方法參考
語法:
類::靜態方法
- 在參考的方法后面,不要添加小括號,
- 參考的這個方法,引數(數量、型別)和回傳值,必須要跟介面中定義的一致,
/**
* @Description: 方法參考
* @author Guoqianliang
* @date 0:26 - 2021/2/16
*/
public class Lambda1 {
private static interface Calculate {
int calculate(int a, int b);
}
private static int calculate(int x, int y) {
if (x > y) {
return x - y;
} else if (x < y) {
return y - x;
}
return x + y;
}
public static void main(String[] args) {
// 靜態方法參考
Calculate calculate = Lambda1::calculate;
System.out.println(calculate.calculate(10, 20));
}
}
2.非靜態方法參考
語法:
物件::非靜態方法
- 在參考的方法后面,不要添加小括號,
- 參考的這個方法,引數(數量、型別)和回傳值,必須要跟介面中定義的一致,
/**
* @Description: 方法參考
* @author Guoqianliang
* @date 0:26 - 2021/2/16
*/
public class Lambda1 {
private static interface Calculate {
int calculate(int a, int b);
}
// 非靜態方法
private int calculate2(int a, int b) {
if (a != b) {
return a - b;
}
return a + b;
}
public static void main(String[] args) {
// 非靜態方法參考
Calculate calculate2 = new Lambda1()::calculate2;
System.out.println(calculate.calculate(10, 20));
}
}
3.構造方法參考
語法:
類名::new
- 可以通過介面中的方法的引數,區分參考不同的構造方法,
- 如果某一個函式式介面中定義的方法,僅僅是為了得到一個類的物件,此時就可以使用構造方法的參考,簡化這個方法的實作,
/**
* @Description: 構造方法參考
* @author Guoqianliang
* @date 11:20 - 2021/2/16
*/
public class Lambda2 {
@FunctionalInterface
private interface GetPersonWithNoneParameter {
Person get();
}
@FunctionalInterface
private interface GetPersonWithSingleParameter {
Person get(String name);
}
@FunctionalInterface
private interface GetPersonWithMutipleParameter {
Person get(String name, int age);
}
private static class Person {
String name;
int age;
public Person() {
System.out.println("Person類的無參構造方法執行了");
}
public Person(String name) {
this.name = name;
System.out.println("Person類的有參構造方法執行了");
}
public Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Person類的兩個引數的構造方法執行了");
}
}
public static void main(String[] args) {
// 1.使用lambda運算式,實作GetPersonWithNoneParameter介面
GetPersonWithNoneParameter getPerson = Person::new;
// 2.使用lambda運算式,實作GetPersonWithSingleParameter介面
GetPersonWithSingleParameter getPerson2 = Person::new;
// 3.使用lambda運算式,實作GetPersonWithMutipleParameter介面
GetPersonWithMutipleParameter getPerson3 = Person::new;
System.out.println(getPerson.get());
System.out.println(getPerson2.get("樹先生"));
System.out.println(getPerson3.get("你好", 23));
}
}
4.物件方法的特殊參考
使用lambda運算式實作某些介面時,如果lambda運算式中包含了某一個物件,此時方法體中,直接使用這個物件呼叫它的某一個方法就可以完成整體的邏輯,
/**
* @Description: 物件方法的特殊應用
* @author Guoqianliang
* @date 11:54 - 2021/2/16
*/
public class Lambda3 {
@FunctionalInterface
private interface MyInterface {
// String get(Person person);
void set(Person person, String name);
}
private static class Person {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public static void main(String[] args) {
Person p1 = new Person();
p1.setName("小明");
// 邏輯實作只是為了獲取到物件的名字
// MyInterface lambda2 = Person::getName;
// System.out.println(lambda2.get(p1));
// 邏輯實作只是為了給物件的某些屬性進行賦值
MyInterface lambda1 = (x, n) -> x.setName(n);
MyInterface lambda2 = Person::setName;
lambda2.set(p1, "李華");
System.out.println(p1.getName());
}
}
四、Lambda運算式需要注意的問題
如果用到
區域變數,默認會被宣告為常量,不能發生值的改變,
/**
* @Description:
* @author Guoqianliang
* @date 13:05 - 2021/2/16
*/
public class Lambda4 {
public static void main(String[] args) {
// 1.定義一個區域變數
int x = 10;
// 2.使用lambda運算式實作介面
LambdaTest lambda = () -> {
System.out.println("x=" + x);
};
// 3. 無法修改常量x
// x=20;
}
}
@FunctionalInterface
interface LambdaTest {
void test();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/260399.html
標籤:java
上一篇:Point2D類,JavaSE
