八,Lambda表示式

bjynjj發表於2024-10-18

Java Lambda表示式與列舉

Lambda表示式概述

Java從JDK 1.8開始引入了Lambda表示式,以簡化程式碼開發並支援函數語言程式設計。Lambda表示式可以避免物件導向程式設計中的一些繁瑣問題,但同時也是一把雙刃劍。

Lambda表示式的使用場景

  • 必須有相應的函式介面,即內部有且僅有一個抽象方法的介面。
  • 型別推斷機制,編譯器可以根據上下文資訊推斷出引數列表的型別。

Lambda表示式的優點

  • 匿名函式,可以寫出更簡潔、更靈活的程式碼。
  • 提升了Java的語言表達能力。

Lambda表示式的演化

透過員工過濾年齡和工資的案例,感受Lambda表示式的演化與方便之處。

Lambda表示式的語法

Lambda表示式引入了->運算子,分為兩個部分:左側的引數列表和右側的Lambda體。

分類與格式

  1. 無引數,無返回值
    () -> {
        執行語句
    }
    
  2. 有一個引數,無返回值
    (變數名) -> {
        執行語句
    }
    
  3. 只有一個引數時,小括號可省略
    變數名 -> {
        執行語句
    }
    
  4. 兩個以上引數,有返回值,Lambda體中有多條語句
    (變數名1, 變數名2) -> {
        執行語句;
        return xxx;
    }
    
  5. Lambda體中只有一條語句時,可省略return和大括號
    (變數名1, 變數名2) -> 要返回的結果;
    
  6. 型別推斷
    ([型別] 變數名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之前使用列舉

  1. 建立列舉類的屬性必須是私有常量。
  2. 構造方法必須私有化。
  3. 提供公共的靜態final方法獲取列舉物件。
  4. 提供公共的獲取屬性的方法。
  5. 重寫toString()方法。

JDK1.5之後使用列舉

  1. 列舉物件放在開頭。
  2. 建立列舉類的屬性必須是私有常量。
  3. 構造方法必須私有化。
  4. 提供公共的獲取屬性的方法。
  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());
    }
}

相關文章