Java Lambda表示式與列舉
Lambda表示式概述
Java從JDK 1.8開始引入了Lambda表示式,以簡化程式碼開發並支援函數語言程式設計。Lambda表示式可以避免物件導向程式設計中的一些繁瑣問題,但同時也是一把雙刃劍。
Lambda表示式的使用場景
- 必須有相應的函式介面,即內部有且僅有一個抽象方法的介面。
- 型別推斷機制,編譯器可以根據上下文資訊推斷出引數列表的型別。
Lambda表示式的優點
- 匿名函式,可以寫出更簡潔、更靈活的程式碼。
- 提升了Java的語言表達能力。
Lambda表示式的演化
透過員工過濾年齡和工資的案例,感受Lambda表示式的演化與方便之處。
Lambda表示式的語法
Lambda表示式引入了->
運算子,分為兩個部分:左側的引數列表和右側的Lambda體。
分類與格式
- 無引數,無返回值
() -> { 執行語句 }
- 有一個引數,無返回值
(變數名) -> { 執行語句 }
- 只有一個引數時,小括號可省略
變數名 -> { 執行語句 }
- 兩個以上引數,有返回值,Lambda體中有多條語句
(變數名1, 變數名2) -> { 執行語句; return xxx; }
- Lambda體中只有一條語句時,可省略return和大括號
(變數名1, 變數名2) -> 要返回的結果;
- 型別推斷
([型別] 變數名1, [型別] 變數名2) -> 要返回的結果;
總結口訣
上聯:左右遇一括號省
下聯:左側推斷型別省
橫批:能省則省
Java內建函式式介面
Java在java.util.function
包下提供了多個內建函式式介面,如Predicate<T>
、Function<T,R>
、Supplier<T>
和Consumer<T>
。
Predicate 斷言型介面
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
Function<T,R> 函式型介面
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
Supplier 供給型介面
@FunctionalInterface
public interface Supplier<T> {
T get();
}
Consumer 消費型介面
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
Lambda用法再簡潔之方法引用
物件引用
物件引用::例項方法名
類引用
類名::靜態方法名
類::例項方法名
變數1對應的類名::例項方法名
構造方法引用
類名::new
陣列引用
元素型別[]::new
誤區
Lambda表示式並不是匿名內部類的實現,而是透過invokedynamic
指令呼叫。
小結
Lambda表示式的優點是可以減少程式碼量,節省記憶體佔用,但易讀性較差,不方便除錯。
新特性2:列舉
列舉概述
列舉型別用於統一管理有限的常量資料,提高程式碼的可讀性和簡潔性。
JDK1.5之前使用列舉
- 建立列舉類的屬性必須是私有常量。
- 構造方法必須私有化。
- 提供公共的靜態final方法獲取列舉物件。
- 提供公共的獲取屬性的方法。
- 重寫
toString()
方法。
JDK1.5之後使用列舉
- 列舉物件放在開頭。
- 建立列舉類的屬性必須是私有常量。
- 構造方法必須私有化。
- 提供公共的獲取屬性的方法。
- 重寫
toString()
方法。
列舉類實現介面
列舉類可以實現介面,並且列舉中的每個物件可以單獨實現介面。
/*
1. 建立列舉類的屬性(成員遍歷),必須是作為私有常量出現
2. 必須將構造方法私有化,這是為了保證類的物件是有限個的目的
3. 提供公共的靜態的final方法給外界獲取列舉類中多個物件
4. 提供公共的獲取屬性的方法
5. 重寫toString()方法
*/
class Season{
//1. 建立列舉類的屬性(成員遍歷),必須是作為私有常量出現
private String name;
private String info;
//2. 必須將構造方法私有化,這是為了保證類的物件是有限個的目的
private Season(String name, String info){
this.name = name;
this.info = info;
}
//3. 提供公共的靜態的final方法給外界獲取列舉類中多個物件
public static final Season SPRING = new Season("春天","春暖花開");
public static final Season SUMMER = new Season("夏天","烈日炎炎");
public static final Season AUTUMN = new Season("秋天","秋高氣爽");
public static final Season WINTER = new Season("冬天","白雪皚皚");
//4. 提供公共的獲取屬性的方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
@Override
public String toString() {
return "Season{" +
"name='" + name + '\'' +
", info='" + info + '\'' +
'}';
}
}
public class SeasonDemo1 {
public static void main(String[] args) {
Season spring = Season.SPRING;
Season summer = Season.SUMMER;
}
}
/*
jdk1.5之後 java提供了一個關鍵字用於建立列舉類 enum
*/
enum Season2{
//jdk1.5之後必須將有限個物件放在enum列舉類第一個開頭位置,多個物件之間使用逗號隔開
SPRING("春天","春暖花開"),
SUMMER("夏天","烈日炎炎"),
AUTUMN("秋天","秋高氣爽"),
WINTER("冬天","白雪皚皚");
//1. 建立列舉類的屬性(成員遍歷),必須是作為私有常量出現
private String name;
private String info;
//2. 必須將構造方法私有化,這是為了保證類的物件是有限個的目的
private Season2(String name, String info){
this.name = name;
this.info = info;
}
//4. 提供公共的獲取屬性的方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
@Override
public String toString() {
return "Season{" +
"name='" + name + '\'' +
", info='" + info + '\'' +
'}';
}
}
public class SeasonDemo2 {
public static void main(String[] args) {
Season2 spring = Season2.SPRING;
System.out.println(spring.getName());
System.out.println(spring.getInfo());
}
}