函數式編程/lambda表達式入門

函數式編程/lambda表達式入門

本篇主要講解 lambda表達式的入門,涉及爲什麼使用函數式編程,以及jdk8提供的函數式接口 和 接口的默認方法 等等

1.什麼是命令式編程

命令式編程就是我們去告訴程序如何實現

比如在一堆數字中尋找最小值

    int[] nums = {33, 44, 55, -111, -1};

    int minNum = Integer.MAX_VALUE;

    for (int num : nums) {
        if (num < minNum) {
            minNum = num;
        }
    }

    System.out.println(minNum);

這段代碼就是命令式編程,我們去告訴程序如何從一堆數字中找到最小值

1.什麼是函數式編程

它不是一種具體的技術,是一種方法論,使用對應提供的函數進行編程,而不是去關心內部的實現

比如在一堆數字中尋找最小值

int[] nums = {33, 44, 55, -111, -1};

int min = IntStream.of(nums).min().getAsInt();
System.out.println(min);

IntStream.of(nums).min() 中就是面向函數式編程,你不需要去實現具體的邏輯,只需要簡單調用

2.函數式編程的好處

2.1 易於併發編程 parallel()

比如在一堆數字中尋找最小值

當這堆數字很大的時候,我們需要去實現多線程去比較的話,需要考慮多線程,線程池以及拆分數據,實現快排等。。
但是當我們使用JDK8函數式編程的時候可以直接使用一個方法開啓 並行 .parallel()

int min = IntStream.of(nums).parallel().min().getAsInt();

2.2 代碼簡潔

可以明顯看出來函數式編程代碼簡潔了很多

int[] nums = {33, 44, 55, -111, -1};

 函數式編程:   int min = IntStream.of(nums).parallel().min().getAsInt();

 命令式編程:   

    int minNum = Integer.MAX_VALUE;

    for (int num : nums) {
        if (num < minNum) {
            minNum = num;
        }
    }

    System.out.println(minNum);

2.3 等等。。。

3.lambda 表達式初接觸

在Java中我們創建線程會使用這種方式,弄一個匿名內部類去實現Runnable接口,但是線程執行的核心代碼 只是run方法裏面的
但是我們需要用這麼多行代碼去實現,實在不是很友好

    new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("lambda 初識");
        }
    }).start();

lambda表達式的方式 實現創建一個線程

    new Thread(() -> System.out.println("lambda 初識")).start();

可以看出來比上面匿名內部類要簡單很多

在Java8中用使用 -> 函數來編寫lambda表達式, lambda表達式會返回一個函數

Runnable runnable = () -> System.out.println("lambda 初識");

lambda表達式不關心你要實現的是什麼接口,只是關心你的入參和返回值 ,如下

interface  MyFunction{
    void hello();
}
 MyFunction myFunction = () -> System.out.println("lambda 初識");

4.JDK8中的函數式接口

4.1 概念:

函數式接口是JDK8中引入的概念,對應的註解是 @FunctionalInterface 標註在接口上表示這個接口只有一個方法(不算默認方法) 如下

@FunctionalInterface
interface Interface1 {
   int doubleNumber(int i);
}

4.2 @FunctionalInterface

@FunctionalInterface 這個註解只是起到編譯時的檢查,不加也行 但是推薦要加上

Interface1 interface1 = (i) -> i * 2;

當我們在標註了@FunctionalInterface這個註解的接口裏添加了 2個或者多個方法的時候 會產生編譯錯誤

@FunctionalInterface  
interface Interface1 {
  int doubleNumber(int i);
  void someMethod();
}

當我們仔細觀察 會發現lambda 表達式只是關注的入參和返回值,也就是說可以把這個lambda表達式賦給任何的有一個參數有一個返回值的函數式接口上

Interface1 interface1 = (i) -> i * 2;

這時候就引入了JDK8提供的默認的函數式接口,大多數情況下就不用我們自己去定義接口了

4.3 默認函數式接口

Xnip20200219_174624.png

使用默認的Function函數式接口

Function<Integer , Integer> function = (i) -> i * 2;
function.apply(10);

使用默認的Predicate函數式接口

 Predicate<Integer> predicate = (i) -> i % 2 == 0;
 predicate.test(2);

5.JDK8接口新特性 默認方法

JKD8接口新特性 默認方法,這個新特性其實是很重要的,它的作用就是在接口上可以定義方法的實現 作爲默認方法,這樣
Java就可以擴展很多底層接口 比如List接口 ,對其添加了很多default默認方法,這時候List的接口的實現類也不用去修改了

前面有介紹關於@FunctionalInterface 會檢測該接口有幾個待實現的方法,如果有多個則編譯不通過,但是
當我們在另一個方法上面添加 default

@FunctionalInterface  
interface Interface1 {
  int doubleNumber(int i);
  void someMethod();
}

-》 如下添加default ,此時接口Interface1 還是保持一個待實現的接口,此時@FunctionalInterface編譯就能通過

@FunctionalInterface
interface Interface1 {
  int doubleNumber(int i);

  default void someMethod(){
    System.out.println("Interface1 default Method ");
 }
}

如List提供了 一個sort的default方法,這是以前List接口沒有的

Xnip20200219_184740.png

6.總結

本篇主要講解 lambda表達式的入門,涉及函數式編程和命令式編程的區別,以及jdk8提供的函數式接口 和 接口的默認方法 等等該篇只涉及入門概念,具體深入理解還是需要自己去實踐,最近準備學習Webflux 所以需要複習一下Java8 lambda 以及 Stream流

個人博客地址: https://www.askajohnny.com 歡迎訪問!
本文由博客一文多發平臺 OpenWrite 發佈!

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