首頁  >  文章  >  Java  >  java8保姆級lambda表達式原始碼分析

java8保姆級lambda表達式原始碼分析

WBOY
WBOY轉載
2023-04-14 23:04:031191瀏覽

1.替代匿名內部類別

毫無疑問,lambda表達式用得最多的場合就是替代匿名內部類,而實作Runnable介面是匿名內部類別的經典範例。 lambda表達式的功能相當強大,用()->就可以取代整個匿名內部類別!請看程式碼:

如果使用匿名內部類別:

    @Test
    public void oldRunable() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("The old runable now is using!");
            }
        }).start();
    }

而如果使用lambda表達式:

    @Test
    public void runable() {
        new Thread(() -> System.out.println("It's a lambda function!")).start();
    }

最後的輸出:

The old runable now is using!

It's a lambda function!

是不是強大到可怕?是不是簡單到可怕?是不是清晰明了重點突出到可怕?這就是lambda表達式的可怕之處,用極少的程式碼完成了之前一個類別做的事情!

2.使用lambda表達式對集合進行迭代

Java的集合類別是日常開發中常用到的,甚至說沒有哪個java程式碼中沒有使用到集合類別。 。 。而對集合類別最常見的操作就是進行迭代遍歷了。請看對比:

    @Test
    public void iterTest() {
        List<String> languages = Arrays.asList("java","scala","python");
        //before java8
        for(String each:languages) {
            System.out.println(each);
        }
        //after java8
        languages.forEach(x -> System.out.println(x));
        languages.forEach(System.out::println);
    }

如果熟悉scala的同學,肯定對forEach不陌生。它可以迭代集合中所有的對象,並將lambda表達式帶入其中。

languages.forEach(System.out::println);

這一行看起來有點像c 裡面作用域解析的寫法,這裡也是可以的。

3.用lambda表達式實作map

一提到函數式編程,一提到lambda表達式,怎麼能不提map。 。 。沒錯,java8肯定也是支援的。請看範例程式碼:

    @Test
    public void mapTest() {
        List<Double> cost = Arrays.asList(10.0, 20.0,30.0);
        cost.stream().map(x -> x + x*0.05).forEach(x -> System.out.println(x));
    }

最後的輸出結果:

10.5

21.0

31.5

# map函數可以說是函數式程式設計裡最重要的方法了。 map的作用是將一個物件轉換為另外一個。在我們的例子中,就是透過map方法將cost增加了0,05倍的大小然後輸出。

4.用lambda表達式實作map與reduce

既然提到了map,又怎麼能不提到reduce。 reduce與map一樣,也是函數式程式設計裡最重要的幾個方法之一。 。 。 map的作用是將一個物件變成另外一個,而reduce實作的則是將所有值合併為一個,請看:

    @Test
    public void mapReduceTest() {
        List<Double> cost = Arrays.asList(10.0, 20.0,30.0);
        double allCost = cost.stream().map(x -> x+x*0.05).reduce((sum,x) -> sum + x).get();
        System.out.println(allCost);
    }

最終的結果為:

 63.0

如果我們用for迴圈來做這件事情:

    @Test
    public void sumTest() {
        List<Double> cost = Arrays.asList(10.0, 20.0,30.0);
        double sum = 0;
        for(double each:cost) {
            each += each * 0.05;
            sum += each;
        }
        System.out.println(sum);
    }

相信用map reduce lambda表達式的寫法高出不只一個level。

5.filter運算

filter也是我們常用的一個動作。在運算集合的時候,經常需要從原始的集合中過濾掉一部分元素。

    @Test
    public void filterTest() {
        List<Double> cost = Arrays.asList(10.0, 20.0,30.0,40.0);
        List<Double> filteredCost = cost.stream().filter(x -> x > 25.0).collect(Collectors.toList());
        filteredCost.forEach(x -> System.out.println(x));

    }

最後的結果:

30.0

40.0

將java寫出了python或scala的感覺有沒有!是不是帥到爆!

6.與函數式介面Predicate配合

除了在語言層面支援函數式程式設計風格,Java 8也加入了一個包,叫做 java.util.function。它包含了很多類,用來支援Java的函數式程式設計。其中一個便是Predicate,使用 java.util.function.Predicate 函數式介面以及lambda表達式,可以為API方法添加邏輯,用更少的程式碼支援更多的動態行為。 Predicate介面非常適合做過濾。

    public static void filterTest(List<String> languages, Predicate<String> condition) {
        languages.stream().filter(x -> condition.test(x)).forEach(x -> System.out.println(x + " "));
    }

    public static void main(String[] args) {
        List<String> languages = Arrays.asList("Java","Python","scala","Shell","R");
        System.out.println("Language starts with J: ");
        filterTest(languages,x -> x.startsWith("J"));
        System.out.println("\nLanguage ends with a: ");
        filterTest(languages,x -> x.endsWith("a"));
        System.out.println("\nAll languages: ");
        filterTest(languages,x -> true);
        System.out.println("\nNo languages: ");
        filterTest(languages,x -> false);
        System.out.println("\nLanguage length bigger three: ");
        filterTest(languages,x -> x.length() > 4);
    }

最後的輸出結果:

##Language starts with J: 

Java 

Language ends with a: 

Java 
scala 

All languages: 

Java 
Python 
scala 
Shell 

No languages: 

#Language length bigger# #Python 

scala 
Shell 

可以看到,Stream API的過濾方法也接受一個Predicate,這意味著可以將我們自訂的filter() 方法替換成寫在裡面的內聯程式碼,這也是lambda表達式的魔力。

以上是java8保姆級lambda表達式原始碼分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除