函數式編程/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 發佈!