Java中Lambda表達式的學習

先來個小例子看下,有個直觀的瞭解。

//1.首先,要定義一個函數式接口
//即Functional Interface,就是隻有一個抽象方法的接口。

public interface Func {
    double func(double x);
}

//2.測試
public void testLambda() {
    //定義一個數學函數:f(x) = x^2
    //如果用lambda表達式,則寫法如下:
    Func f1 = (x)->x*x;
    //同理,定義一個數學函數:f(x) = x^3
    Func f2 = (x)->x*x*x;

    //如果用匿名內部類的話,寫法如下:
    // Func f1 = new Func() {
    //     public double func(double x) {
    //         return x*x;
    //     }
    // }

    //定義自變量
    double x = 8;
    //相當於y = f(x)
    double y1 = f1.func(x);
    double y2 = f2.func(x);
    //輸出結果
    System.out.println(y1);
    System.out.println(y2);
}

從上面看出,lambda表達式首先需要一個函數式接口,然後採用lambda實現該接口(等價於匿名內部類)。實現形式有兩種:

(傳入參數) -> 你要做的事情
//或者
(傳入參數) -> { 你要做的事情 }

注意的是,這裏lambda和匿名內部類一樣,不能對外部變量變量進行修改(原話是Local variable defined in an enclosing scope must be final or effectively final,也就是說,如果使用閉合作用域中的變量,那麼這個變量必須是final或事實final,說白了,不能修改),如下,PI作爲一個參數可以在lambda中使用,但是不能在其中修改:

@Test
public void testLambda2() {
    double PI = 3.1415926535897932384626;
    //求圓的面積公式
    Func S = (r) -> PI * r * r;

    //求解過程
    double x = 10.0;
    double y = S.func(x);

    System.out.println("y = " + y);

}

儘管使用上,lambda與匿名內部類相似,然而,lambda與匿名內部類有一些深層次的差異:
1. 匿名類的 this 關鍵字指向匿名類,而lambda表達式的 this 關鍵字指向包圍lambda表達式的類
2. Java編譯器將lambda表達式編譯成類的私有方法

下面來點稍微高級的用法:

/**
 * 求解一個list中的所有數據的平方
 */
@Test
public void testLambda1() {
    //定義一個Double型的List
    List<Double> list = Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0);
    //定義一個存放結果的List
    List<Double> list2 = new ArrayList<>();

    //將list中每個數求平方,然後放到list2中
    //這裏的forEach方法是JDK1.8中引入的
    list.forEach((a)->list2.add(a*a));

    //打印結果
    System.out.println(list);
    System.out.println(list2);
}

排序中採用lambda代替匿名內部類

@Test
public void testLambda3() {
    //定義測試list
    List<Double> list = Arrays.asList(1.0, 9.0, 4.0, 11.0, 33.0, 24.0, 12.0, 2.0, 3.0, 4.0, 5.0);
    //調用工具類Collections的排序方法,傳入一個排序規則
    //這裏的lambda說白了就是實現了Comparator的匿名內部類
    Collections.sort(list, (x, y) -> (int)Math.ceil(x - y));
    //輸出結果
    System.out.println(list);
}

這寫用法看起來很炫,有些也確實很實用,但是不知道這種語法能不能普及

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章