1. 程式人生 > >函數語言程式設計/lambda表示式入門

函數語言程式設計/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 預設函式式介面

使用預設的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介面沒有的

6.總結

本篇主要講解 lambda表示式的入門,涉及函數語言程式設計和指令式程式設計的區別,以及jdk8提供的函式式介面 和 介面的預設方法 等等該篇只涉及入門概念,具體深入理解還是需要自己去實踐,最近準備學習Webflux 所以需要複習一下Java8 lambda 以及 Stream流

個人部落格地址: https://www.askajohnny.com 歡迎訪問!
本文由部落格一文多發平臺 OpenWrite 釋出!