Java - Lambda表達式

你之因此能優於別人,正是由於你堅持了別人所不能堅持的。
本文相關代碼在個人Github,歡迎Star~
https://github.com/zhangzhibo1014/DaBoJava

Lambda

Lambda 是一個匿名函數,是一個可傳遞的代碼塊,能夠在之後執行一次或屢次。使用 Lambda 表達式,能夠寫出更加緊湊、更加簡潔、更加靈活的代碼。java

語法

(parameters) -> expression
(parameters) -> { statements; }
(參數) -> 方法體(表達式/代碼塊)

使用的限制

Lambda 並非任何地方均可以使用,Lambda 表達式須要「函數式接口」的支持。git

函數式接口

接口中只有一個抽象方法的接口,稱爲函數式接口,能夠用 @FunctionalInterface 修飾一下,這裏須要注意的是:未使用 @FunctionalInterfaces 註解的接口未必就不是函數式接口,一個接口是否是函數式接口的條件只有一條,即接口中只有一個抽象方法的接口( Object 類中的方法不算)。而使用 @FunctionalInterface 註解修飾了的接口就必定是函數式接口,添加 @FunctionalInterface 註解能夠幫助咱們檢查是不是函數式接口。github

經常使用的函數式接口

Consumer<T> : 消費型接口(無返回值,有去無回)
         void accept(T t);
 Supplier<T> : 供給型接口
         T get();
         
 Function<T,R> : 函數型接口
        R apply(T t);
        
 Predicate<T> : 斷言型接口
        boolean test(T t);
        
四大核心接口的-->擴展子接口

@FunctionalInterface
public interface Runnable {

    public abstract void run();
}

@FunctionalInterface
public interface Supplier<T> {

    T get();
}

@FunctionalInterface
public interface Consumer<T> {

    void accept(T t);
    
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

其餘的相似,這些函數式接口都在java.util.function包下,讀者可去這個包下去查詢。

Lamdba表達式的重要特徵

  • 可選的類型聲明:不須要聲明參數類型,編譯器能夠統一識別參數值
  • 可選的參數周圍的括號:一個參數無需定義圓括號,但多個參數須要定義圓括號。
  • 可選的大括號:若是表達式體裏面只有一個語句,那麼你沒必要用大括號括起來。
  • 可選的返回關鍵字:若是表達式體只有單個表達式用於值的返回,那麼編譯器會自動完成這一步。若要指示表達式來返回某個值,則須要使用大括號。

Lambda表達式實例

1.不須要參數
    () -> 5
2.接收一個參數
    x -> x * 2
3.接收兩個參數
    (int x, int y) -> x * y
    (x, y) -> x - y
4.接收一個 String 對象
    (String s) -> System.out.println(s)
/**
 * lambda表達式
 */
public class Demo {

    public static void main(String[] args) {
        Demo demo = new Demo();
        // 表達式
        Cal addCal = (x, y) ->  x + y;

        Cal subCal = (int x, int y) -> {return (x - y); };

        Cal mulCal = (x, y) -> x * y;

        Cal divCal = (int x, int y) ->  x / y;

        System.out.println("10 + 2 =" + demo.cals(10, 2, addCal));
        System.out.println("10 - 2 =" + demo.cals(10, 2, subCal));
        System.out.println("10 * 2 =" + demo.cals(10, 2, mulCal));
        System.out.println("10 / 2 =" + demo.cals(10, 2, divCal));
    }

    public static int cals(int a, int b, Cal cal) {
        return cal.calNumbers(a,b);
    }
}

interface Cal{
    int calNumbers(int a, int b);
}

方法引用

方法也是一種對象,能夠經過名字來引用。不過方法引用的惟一用途是支持Lambda的簡寫,使用方法名稱來表示Lambda。不能經過方法引用來得到諸如方法簽名的相關信息。express

方法引用能夠經過方法的名字來引用其自己。方法引用是經過::符號(雙冒號)來描述的。微信

  • 構造器引用。語法是Class::new,或者更通常的Class< T >::new,要求構造器方法是沒有參數
  • 靜態方法引用。語法是Class::static_method,要求接受一個Class類型的參數
  • 特定對象的方法引用,它的語法是instance::method。要求方法接受一個參數
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * 方法引用
 */
public class Demo1 {
    public static void main(String[] args) {
        //構造方法
        Supplier<DaBoJava> supplier = DaBoJava::new;
        System.out.println(supplier.get());
        //靜態方法
        Consumer<String> consumer = DaBoJava::staticMethod;
        consumer.accept("DaBoJava");
        //對象方法
        DaBoJava daBoJava = new DaBoJava();
        Consumer<String> consumer1 = daBoJava::method;
        consumer1.accept("instance");
    }
}

class DaBoJava{
    public DaBoJava() {
    }
    public static void staticMethod(String name) {
        System.out.println(name);
    }
    public void method(String name){
        System.out.println(name);
    }
}

總結

Lambda 雖然代碼看上去簡潔,可是若是複雜的話仍是比較難看明白的。app

在學習 Lambda 的時候,咱們應該清楚有哪些常見的函數式接口,而且瞭解相應的函數式接口的用法(參數,返回值類型)函數

Lambda 表達式返回的是 接口對象實例 ,若是 函數式接口的實現剛好能夠經過調用一個方法來實現 ,那麼咱們可使用方法引用來替代Lambda表達式學習

相關代碼記錄於 GitHub中,歡迎各位夥伴 Star

有任何疑問 微信搜一搜 [程序猿大博] 與我聯繫~ui

若是以爲對您有所幫助,請 點贊收藏 ,若有不足,請評論或私信指正,謝謝~code

相關文章
相關標籤/搜索