亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

函數式編程

2019-11-14 11:11:05
字體:
來源:轉載
供稿:網友

為什么要用函數式編程。看例子:

final List<BigDecimal> PRices = Arrays.asList(    new BigDecimal("10"), new BigDecimal("30"), new BigDecimal("17"),    new BigDecimal("20"), new BigDecimal("15"), new BigDecimal("18"),    new BigDecimal("45"), new BigDecimal("12"));BigDecimal totalOfDiscountedPrices = BigDecimal.ZERO;for(BigDecimal price : prices) {    if(price.compareTo(BigDecimal.valueOf(20)) > 0)        totalOfDiscountedPrices = totalOfDiscountedPrices.add(price.multiply(BigDecimal.valueOf(0.9)));}System.out.println("Total of discounted prices: " + totalOfDiscountedPrices);

更優雅的方式,是使用聲明式的代碼:

final BigDecimal totalOfDiscountedPrices =     prices.stream()          .filter(price -> price.compareTo(BigDecimal.valueOf(20)) > 0)          .map(price -> price.multiply(BigDecimal.valueOf(0.9)))          .reduce(BigDecimal.ZERO, BigDecimal::add);System.out.println("Total of discounted prices: " + totalOfDiscountedPrices);

使用函數式代碼的好處:

減少了可變量(Immutable Variable)的聲明能夠更好的利用并行(Parallelism)代碼更加簡潔和可讀

函數式接口

函數式接口就是僅聲明了一個方法的接口,比如我們熟悉的Runnable,Callable,Comparable等都可以作為函數式接口。當然,在java 8中,新添加了一類函數式接口,如Function,Predicate,Consumer,Supplier等。

@FunctionalInterfacepublic static interface IntHandler{    void handle(int i);}

在函數式接口中,可以聲明0個或者多個default方法,這些方法在接口內就已經被實現了。因此,接口的default方法也是Java 8中引入的一個新概念。

default method 默認方法,又稱作虛擬擴展方法或保衛者方法,例子:

import java.util.Objects;import java.util.function.Consumer;public interface Iterable<T> {    default void forEach(Consumer<? super T> action) {        Objects.requireNonNull(action);        for (T t : this) {            action.accept(t);        }    }}

為什么需要default method?

即使你的API已經發布出去了,你依然可以為接口添加新方法并且無需考慮向后兼容問題。java8 對Lambda的支持必然會影響JDK API的接口,如果直接在接口中添加方法,就會導致所有實現該接口的類或者接口無法通過編譯。

函數式接口使用 @FunctionalInterface注解進行標注。雖然這個注解的使用不是強制性的,但是使用它的好處是讓此接口的目的更加明確,同時編譯器也會對代碼進行檢查,來確保被該注解標注的接口的使用沒有語法錯誤。

lambda表達式

lambda表達式即匿名函數,它是一段沒有函數名的函數體,可以作為參數直接傳遞給相關調用者。

Lambda 表達式通常使用 (argument) -> (body) 語法書寫,例如:

(arg1, arg2...) -> { body }(type1 arg1, type2 arg2...) -> { body }

舉例來說:

(int a, int b) -> {  return a + b; }() -> System.out.println("Hello World");(String s) -> { System.out.println(s); }() -> 42() -> { return 3.1415 };

Lambda 表達式的結構

一個 Lambda 表達式可以有零個或多個參數參數的類型既可以明確聲明,也可以根據上下文來推斷。例如:(int a)與(a)效果相同所有參數需包含在圓括號內,參數之間用逗號相隔。例如:(a, b) 或 (int a, int b) 或 (String a, int b, float c)空圓括號代表參數集為空。例如:() -> 42當只有一個參數,且其類型可推導時,圓括號()可省略。例如:a -> return a*aLambda 表達式的主體可包含零條或多條語句如果 Lambda 表達式的主體只有一條語句,花括號{}可省略。匿名函數的返回類型與該主體表達式一致如果 Lambda 表達式的主體包含一條以上語句,則表達式必須包含在花括號{}中(形成代碼塊)。匿名函數的返回類型與代碼塊的返回類型一致,若沒有返回則為空

每個 Lambda 表達式都能隱式地賦值給函數式接口,例如,我們可以通過 Lambda 表達式創建 Runnable 接口的引用。

Runnable r = () -> System.out.println("hello world");

方法引用

方法引用是Java 8中提出的用來簡化lambda表達式的一種手段。它通過類名和方法名來定位到一個靜態方法或者實例方法。 方法引用在Java 8中的使用非常靈活??偟膩碚f,可以分為以下幾種:

靜態方法引用:ClassName::methodName

List<Integer> ints = Arrays.asList(1, 2, 3);ints.sort(Integer::compare);

實例上的實例方法引用 instanceReference::methodName,方法引用使用”::”定義,”::”的前半部分表示類名或者實例名,后半部分表示方法名稱。如果是構造函數,則使用new表示。

Words.forEach(System.out::println);words.stream().map(word -> word.length()); // lambdawords.stream().map(String::length); // method reference// lambdawords.stream().map(word -> {    return new StringBuilder(word);});// constructor referencewords.stream().map(StringBuilder::new);

Lambda 表達式舉例

1.線程初始化

//舊方法:new Thread(new Runnable() {@Overridepublic void run() {    System.out.println("Hello from thread");}}).start();//新方法:new Thread(() -> System.out.println("Hello from thread")).start();

2.打印數組所有元素,在下面的例子中,我們先是用常用的箭頭語法創建 Lambda 表達式,之后,使用 Java 8 全新的雙冒號(::)操作符將一個常規方法轉化為 Lambda 表達式:

//Old way:List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);for(Integer n: list) {   System.out.println(n);}//New way:List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);list.forEach(n -> System.out.println(n));//or we can use :: double colon Operator in Java 8list.forEach(System.out::println);

3.斷言函數式接口使用

import java.util.Arrays;import java.util.List;import java.util.function.Predicate;public class Test {    public static void main(String[] args) {        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);        System.out.println("Print all numbers:");        evaluate(list, n -> true);        System.out.println("Print no numbers:");        evaluate(list, n -> false);        System.out.println("Print even numbers:");        evaluate(list, n -> n % 2 == 0);        System.out.println("Print odd  numbers:");        evaluate(list, n -> n % 2 == 1);        System.out.println("Print numbers greater than 5:");        evaluate(list, n -> n > 5);    }    public static void evaluate(List<Integer> list, Predicate<Integer> predicate) {        for (Integer n : list) {            if (predicate.test(n))                System.out.print(n + " ");        }    }}

Lambda 表達式與匿名類的區別

使用匿名類與 Lambda 表達式的一大區別在于關鍵詞的使用。對于匿名類,關鍵詞 this 解讀為匿名類,而對于 Lambda 表達式,關鍵詞 this 解讀為寫就 Lambda 的外部類。

Lambda 表達式與匿名類的另一不同在于兩者的編譯方法。Java 編譯器編譯 Lambda 表達式并將他們轉化為類里面的私有函數,它使用 Java 7 中新加的 invokedynamic 指令動態綁定該方法

接口與抽象類

雖然 Java 8 的接口的默認方法就像抽象類,能提供方法的實現,但是他們倆仍然是 不可相互代替的:

接口可以被類多實現(被其他接口多繼承),抽象類只能被單繼承。接口中沒有 this 指針,沒有構造函數,不能擁有實例字段(實例變量)或實例方法,無法保存 狀態(state),抽象方法中可以。抽象類不能在 java 8 的 lambda 表達式中使用。從設計理念上,接口反映的是 “like-a” 關系,抽象類反映的是 “is-a” 關系。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久精品国产69国产精品亚洲| 国产成人精品国内自产拍免费看| 另类色图亚洲色图| 狠狠爱在线视频一区| 国产日韩欧美91| 精品久久久av| 国产精品揄拍一区二区| 久久久久久久久91| 精品国产一区二区三区久久狼5月| 2021久久精品国产99国产精品| 日本高清+成人网在线观看| 国产亚洲精品久久久| 不卡中文字幕av| 7777精品久久久久久| 久久久久久网站| 亚洲无限乱码一二三四麻| 欧美成人午夜激情| 国产精品免费久久久久久| 国产精品久久一区主播| 91中文字幕一区| 国产一区二区三区18| 国产第一区电影| 97av在线视频| 色yeye香蕉凹凸一区二区av| 亚洲人成网站色ww在线| 亚洲欧美变态国产另类| 国产欧美日韩精品丝袜高跟鞋| 欧美黑人国产人伦爽爽爽| 欧美亚洲日本网站| 亚洲肉体裸体xxxx137| 国产午夜精品理论片a级探花| 久久久久国产精品免费网站| 国产亚洲精品激情久久| 精品国偷自产在线| 中文字幕亚洲专区| 精品久久久视频| 国产精品久久久久久av福利| 国产欧美久久久久久| 国产热re99久久6国产精品| 日韩中文字幕久久| 欧美精品一本久久男人的天堂| 日韩视频免费在线观看| 国产亚洲精品久久久优势| 456亚洲影院| 亚洲少妇中文在线| 欧美激情精品久久久久久大尺度| 日韩中文字幕不卡视频| 日韩久久免费电影| 日韩视频欧美视频| 国产精品扒开腿做| 亚洲第一色中文字幕| 日韩一区二区三区国产| 日韩欧美高清在线视频| 一区二区国产精品视频| 日韩精品免费观看| 色偷偷av一区二区三区乱| 欧美精品一本久久男人的天堂| 不卡在线观看电视剧完整版| 精品一区精品二区| 亚洲欧洲一区二区三区久久| 91国产视频在线| 日本精品一区二区三区在线播放视频| 国产精品久久久久久久久久免费| 国产精品久久久久久亚洲调教| 91色琪琪电影亚洲精品久久| 日韩中文字幕在线免费观看| 久久综合免费视频| 亚洲一区二区久久久久久久| 国产一区二区三区丝袜| 色综合久久精品亚洲国产| 色哟哟网站入口亚洲精品| 亚洲无av在线中文字幕| 俺去了亚洲欧美日韩| 91亚洲精品一区二区| 91免费看片网站| 久久精品在线视频| 欧美日韩在线视频观看| 亚洲激情在线视频| 中文字幕在线观看亚洲| 亚洲日韩欧美视频一区| 综合网日日天干夜夜久久| 欧美亚州一区二区三区| 亚洲最大福利网站| 国产欧美一区二区三区视频| 91九色单男在线观看| 日韩有码视频在线| 亚洲欧美成人一区二区在线电影| 激情成人中文字幕| 欧美精品在线免费播放| 亚洲成人网在线| 精品视频久久久久久久| 色偷偷亚洲男人天堂| 伊人精品在线观看| 久久视频在线视频| 日韩激情第一页| 亚洲精品乱码久久久久久按摩观| 成人精品网站在线观看| 国产精品久久久av久久久| 国产精品扒开腿做爽爽爽的视频| 日韩电影免费观看在线观看| 亚洲日本aⅴ片在线观看香蕉| 国内精久久久久久久久久人| 欧洲美女免费图片一区| 一区二区三区精品99久久| 成人av电影天堂| 日韩美女免费视频| 欧美国产日韩一区二区在线观看| 欧美高清电影在线看| 亚洲国产天堂久久综合| 57pao成人国产永久免费| 国产精品男人的天堂| 亚洲第一视频在线观看| 欧美国产一区二区三区| 亚洲国产精品久久久久久| 国产综合福利在线| 精品福利免费观看| 91chinesevideo永久地址| 久久激情五月丁香伊人| 日韩中文字幕网址| 国产一区二区三区免费视频| 亚洲第一网中文字幕| 亚洲精品美女久久久久| 日韩久久精品成人| 全亚洲最色的网站在线观看| 热草久综合在线| 亚洲第一男人av| 在线观看日韩av| 欧美丝袜一区二区三区| 国产精品美女www爽爽爽视频| 国产日韩精品视频| 色999日韩欧美国产| 日韩av电影中文字幕| 夜夜躁日日躁狠狠久久88av| 性色av一区二区咪爱| 国产欧美亚洲精品| 亚洲xxx视频| 国产午夜精品久久久| 日韩三级成人av网| 青青草国产精品一区二区| 国产精品入口夜色视频大尺度| 97久久久久久| 色综合91久久精品中文字幕| 国产亚洲欧洲黄色| 国产成人精品一区二区| 色综合久久久久久中文网| 欧美一级淫片videoshd| 国产91亚洲精品| 欧美极度另类性三渗透| 亚洲a∨日韩av高清在线观看| 久久人人爽人人爽人人片av高请| 日韩电视剧在线观看免费网站| 欧美日韩国产在线| 亚洲欧美综合v| 久久噜噜噜精品国产亚洲综合| 欧美激情精品在线| 2019中文字幕在线免费观看| 久久精品视频免费播放| 日韩欧美在线视频| 久久久久久久久久久久久久久久久久av| 91亚洲午夜在线| 日韩激情片免费| 久久久久久久久久国产精品| 日韩精品视频中文在线观看| 色偷偷av一区二区三区乱|