Java-函數式編程(二)Lambda表達式


本文首發:
Java-函數式編程(二)Lambda表達式

“Lambda 表達式”(lambda expression)是一個匿名函數,Lambda表達式基於數學中的λ演算得名,直接對應於其中的lambda抽象(lambda abstraction),是一個匿名函數,即沒有函數名的函數。Lambda表達式可以表示閉包(注意和數學傳統意義上的不同)。

認識lambda

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名內部類的執行");
            }
        }).start();
    }

  

設計匿名內部類的目的,就是為了方便程序猿將代碼作為數據來傳遞。但是你會發現,這個對象看起來是很多余的,所以我們不想傳入對象,只想傳入行為。

new Thread(()->{
    System.out.println("lambda代替內部類");
}).start();

  

和實現某接口的對象不同,我們傳入了一段代碼塊--一個沒有名字的函數。->將參數和表達式主體分開,左邊是參數,右邊是方法體。

Lambda的不同形式

Runnable runnable =  ()-> System.out.println("hello world");

 

該Lambda表達式不包含參數(因為是空括號)。

interface Test{
        void oneParam(String name);
    }

Test test = s -> System.out.println("oneParam方法傳遞參數:"+s);
test.oneParam("我是傳遞的值");

  

控制台輸出:
oneParam方法傳遞參數:我是傳遞的值

  

(lambda只能用於函數式接口),如果參數只包含一個參數,可以省略參數的括號。

interface Test2{
       int add(int a,int b);
 }
Test2 test2 = (x,y) -> x+y;
int add = test2.add(10, 10);
System.out.println(add);

控制台輸出:
20

可以看到,我們在使用lambda的時候創建了一個函數x+yTest2對象不是表示兩個數字的和,而是表示兩個數字相加的代碼。以上的代碼中,參數類型都是由編譯器自己推斷的,同樣,我們可以明確的聲明參數類型:

interface Test3{
        long add(long a,long b);
    }

Test3 test3 = (long x,long y) -> x+y;
long add = test3.add(10, 10);

  

引用值的要求

Error:(25, 64) java: 從lambda 表達式引用的本地變量必須是最終變量或實際上的最終變量

String  name = "FantJ";
        Runnable runnable =  ()-> System.out.println("hello " +name);
        runnable.run();
hello FantJ

上面這段代碼,Lambda可以引用非final變量這個屬性你可以早已了解,但是你更需要知道,java8只是放松了這一語法的限制,但實際上要求該變量還是final。

Java-函數式編程(二)Lambda表達式Java-函數式編程(二)Lambda表達式

可以看到,不管name在使用lambda的前還是后做改動,lambda都會報錯:表達式引用的本地變量必須是最終變量或實際上的最終變量,簡單的,我們可以稱他為既成事實上的final變量。所以,lambda也被稱為閉包。

Lambda表達式類型

java中,所有方法都有返回類型,那lambda返回類型是什么呢。

是接口方法的返回類型。這一點前文有體現過。這里再詳細解釋下。

interface Test{
        void oneParam(String name);
}

拿這個例子來講,oneParam方法表示一種行為:接受一個String,返回void。只要方法名和行為和Lambda表達式匹配即可完成調用。

注意:如果編譯器猜不出參數和返回值的類型,則都將視為Object處理。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM