日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Lambda01 编程范式、lambda表达式与匿名内部类、函数式接口、lambda表达式的写法...

發(fā)布時(shí)間:2024/1/17 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Lambda01 编程范式、lambda表达式与匿名内部类、函数式接口、lambda表达式的写法... 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

1 編程范式

  主要的編程范式有三種:命令式編程,聲明式編程和函數(shù)式編程。

  1.1 命令式編程

    關(guān)注計(jì)算機(jī)執(zhí)行的步驟,就是告訴計(jì)算機(jī)先做什么后做什么

  1.2 聲明式編程

    表達(dá)程序的執(zhí)行邏輯,就是告訴計(jì)算機(jī)要做什么,不指定具體怎么做

  1.3 函數(shù)式編程

    跟聲明式編程類(lèi)似,就是告訴計(jì)算機(jī)做什么,不指定具體怎么做

  參考博文

  1.4 demo實(shí)例

    1.4.1 需求

      隨機(jī)產(chǎn)生一個(gè)int類(lèi)型的數(shù)組,分別利用命令式編程和函數(shù)值編程獲取數(shù)組中的最小值

    1.4.2 思路

      命令式編程:

        隨記產(chǎn)生int類(lèi)型數(shù)組 -> 定義一個(gè)int類(lèi)型變量minNumber并取int的最大值 -> 利用循環(huán)遍歷數(shù)組 -> 將數(shù)組中的每個(gè)元素和minNumber進(jìn)行比較,如果比minNumber小就復(fù)制給minNumber,否則就進(jìn)行下一次循環(huán)

      函數(shù)值編程:

        隨記產(chǎn)生int類(lèi)型數(shù)組 -> 定義一個(gè)int類(lèi)型的變量minNumber并取int的最大值 -> 將數(shù)組轉(zhuǎn)化成流 -> 調(diào)用的流的相關(guān)方法獲取流中的最小值 -> 將獲取到的最小值進(jìn)行類(lèi)型轉(zhuǎn)化后在復(fù)制給minNumber

    1.4.3 代碼實(shí)現(xiàn)

package a_test_demo;import org.junit.Before; import org.junit.Test;import java.util.Arrays; import java.util.Random; import java.util.stream.IntStream;/*** @author 王楊帥* @create 2018-06-24 17:14* @desc**/ public class Case02 {/*** 需求:隨機(jī)產(chǎn)生一個(gè)int類(lèi)型的數(shù)組并通過(guò)命令式編程和函數(shù)式編程分別求出數(shù)組中的最小值*/private int[] nums; // 定義一個(gè)int類(lèi)型的數(shù)組int count = 10; // 數(shù)組長(zhǎng)度Random random; // 隨機(jī)數(shù)對(duì)象 @Beforepublic void init() {random = new Random(); // 實(shí)例化Randomnums = new int[count]; // 實(shí)例化數(shù)組for (int i = 0; i < nums.length; i++) { // 修改數(shù)組內(nèi)容nums[i] = random.nextInt(30);} // System.out.println(Arrays.toString(nums)); // 打印數(shù)組信息【測(cè)試用】 }/*** 利用命令式編程實(shí)現(xiàn)*/@Testpublic void test01() {int minNumber = Integer.MAX_VALUE; // 存儲(chǔ)最小值【初始化時(shí)時(shí)最大值】for (int i = 0; i < nums.length; i++) {if (minNumber > nums[i]) {minNumber = nums[i];}}System.out.println(Arrays.toString(nums) + " 中的最小值為: " + minNumber);}/*** 利用函數(shù)式編程實(shí)現(xiàn)*/@Testpublic void test02() {int minNumber = Integer.MAX_VALUE;minNumber = IntStream.of(nums) // 將數(shù)組轉(zhuǎn)化成流.parallel() // 設(shè)置并行處理【PS: 如果是命令式編程需要自己實(shí)現(xiàn)相應(yīng)邏輯】.min() // 獲取流中的最小值.getAsInt(); // 將值轉(zhuǎn)化成int類(lèi)型 System.out.println(Arrays.toString(nums) + " 中的最小值為: " + minNumber);}} View Code

?

2 lambda表達(dá)式與匿名內(nèi)部類(lèi)

  2.1 需求

    現(xiàn)有一個(gè)名為getName的方法,該方法的參數(shù)是一個(gè)Student接口;怎么調(diào)用getName方法

  2.2 思路

    2.2.1 思路一

      創(chuàng)建一個(gè)名為StudentImpl的類(lèi),該類(lèi)實(shí)現(xiàn)了Student接口 -> 調(diào)用getName方法時(shí)傳入StudentImpl的實(shí)例即可

    2.2.2 思路二

      利用匿名內(nèi)部類(lèi)作為getName方法的實(shí)參

    2.2.3 思路三

      利用lambda表達(dá)式作為getName方法的實(shí)參

  2.3 代碼實(shí)現(xiàn)

package a_test_demo;import org.junit.Test;public class Case01 {/*** getName方法:用戶打印學(xué)生的姓名* @param student Student接口*/public void getName(Student student) {System.out.println("學(xué)生的姓名為:" + student.name());}/*** 利用實(shí)現(xiàn)類(lèi)實(shí)現(xiàn)*/@Testpublic void test01() {Student student = new StudentImpl();getName(student);}/*** 利用匿名內(nèi)部類(lèi)實(shí)現(xiàn)*/@Testpublic void test02() {getName(new Student() {@Overridepublic String name() {return "fury";}});}/*** 利用lambda表達(dá)式實(shí)現(xiàn)*/@Testpublic void test03() {getName(() -> "zeus");}}/*** Student接口*/ interface Student {/*** 抽象方法:返回String類(lèi)型的姓名* @return*/String name(); }/*** Student接口的實(shí)現(xiàn)類(lèi)*/ class StudentImpl implements Student {@Overridepublic String name() {return "warrior";} } View Code

  2.4 三種方法使用場(chǎng)景

    2.4.1 實(shí)現(xiàn)類(lèi)

      當(dāng)某個(gè)類(lèi)需要實(shí)例化多次時(shí)使用

    2.4.2 匿名內(nèi)部類(lèi)

      某個(gè)類(lèi)只需要實(shí)例化一次而且不需要知道實(shí)例名稱(chēng)時(shí)使用【通常這個(gè)類(lèi)需要進(jìn)行重寫(xiě)的方法不止一個(gè)】;如果需要知道實(shí)例名稱(chēng)時(shí)就需要使用內(nèi)部類(lèi)

    2.4.3 lambda表達(dá)式

      某個(gè)類(lèi)需要實(shí)例化一次而且不需要知道實(shí)例名字【這個(gè)類(lèi)中通常有且只有一個(gè)需要重寫(xiě)的方法】

  2.5 為什么Lambda表達(dá)式可以作為方法的參數(shù)呢

    Lambda 可以作為方法的參數(shù)。Lambda 表達(dá)式函數(shù)式接口實(shí)現(xiàn)類(lèi)的實(shí)例,所以,Lambda 表達(dá)式作為方法的參數(shù),實(shí)際就是把一個(gè)類(lèi)實(shí)例作為方法的參數(shù)。Lambda 表達(dá)式表達(dá)或是設(shè)計(jì)了一組功能,把它傳遞給方法作為參數(shù),實(shí)際上,可以理解為把一組功能傳遞給了方法。因此,為了讓代碼更加簡(jiǎn)潔,編程更加高效,調(diào)用方法(該方法的參數(shù)類(lèi)型是接口類(lèi)型)時(shí),若接口有多個(gè)抽象方法,我們可以創(chuàng)建這個(gè)接口的匿名實(shí)現(xiàn)類(lèi)的實(shí)例,作為方法的參數(shù)。若是接口只有唯一一個(gè)抽象方法,比如函數(shù)式接口,我們可以創(chuàng)建這個(gè)接口的 Lambda 表達(dá)式,作為調(diào)用方法的參數(shù),把一組功能傳遞給方法。

    技巧01:lambda表達(dá)式 “->” 左邊相當(dāng)于函數(shù)式接口中那個(gè)方法的形參,“->” 的右邊相當(dāng)于函數(shù)式接口中那個(gè)方法的返回值

??        

    技巧02:函數(shù)式接口就是只有一個(gè)抽象方法的接口

?

3 函數(shù)式接口

  就是只有一個(gè)抽象函數(shù)的接口

  3.1 默認(rèn)實(shí)現(xiàn)的方法

    如果一個(gè)函數(shù)式接口中有一個(gè)方法有default修飾,那么這個(gè)方法就叫做默認(rèn)實(shí)現(xiàn)的方法【即:在接口中已經(jīng)實(shí)現(xiàn)了方法相應(yīng)的邏輯(從JDK1.8新增的特性)】,那么這個(gè)默認(rèn)實(shí)現(xiàn)的方法不會(huì)算作是函數(shù)式接口的抽象方法,因?yàn)楹瘮?shù)式接口的定義是:接口中只有一個(gè)抽象方法。

@FunctionalInterface interface IntFace {int doubuleNum(int i); // int test(); // 加了這個(gè)方法后,就會(huì)報(bào)錯(cuò)/*** 默認(rèn)實(shí)現(xiàn)的方法【即:接口中的方法已經(jīng)實(shí)現(xiàn)了業(yè)務(wù)邏輯】* @param a* @param b* @return*/default int add(int a, int b) {return a + b;}}

  3.2 注解 @FunctionalInterface

    該注解的作用是標(biāo)名接口是函數(shù)式接口,并對(duì)該接口進(jìn)行檢查,如果有超過(guò)一個(gè)抽象方法就會(huì)報(bào)錯(cuò)

    技巧01:如果某個(gè)接口中只有一個(gè)抽象方法,那么會(huì)被默認(rèn)為是一個(gè)函數(shù)式接口,不用添加@FunctionalInterface注解也可以,@FunctionalInterface注解只是一個(gè)信息型注解而已

  3.3 自定義函數(shù)式接口

    3.3.1 需求

      自定義一個(gè)函數(shù)式接口MoneyFormat,該接口中有一個(gè)接收int類(lèi)型并且返回String類(lèi)型的抽象方法format;MyMoney類(lèi)中有一個(gè)printMoney方法的參數(shù)類(lèi)型是MoneyFormat;創(chuàng)建MyMoney后如何調(diào)用printMoney方法

/*** 自定義函數(shù)式接口*/ @FunctionalInterface interface MoneyFormat {String format(int money); }/*** 自定義類(lèi)*/ class MyMoney {private int money;/*** 有參構(gòu)造器* @param money*/public MyMoney(int money) {this.money = money;}/**** @param moneyFormat 自定義函數(shù)式接口類(lèi)型*/public void printMoney(MoneyFormat moneyFormat) {System.out.println("我的存款為:" + moneyFormat.format(this.money));} } View Code

    3.3.2 思路

      實(shí)現(xiàn)類(lèi)實(shí)現(xiàn):太low,很麻煩,需要?jiǎng)?chuàng)建一個(gè)MoneyFormat的實(shí)現(xiàn)類(lèi)

      匿名內(nèi)部類(lèi)實(shí)現(xiàn):還行,但是不美觀

      lambda:簡(jiǎn)單、粗暴、有成效

package a_test_demo;import org.junit.Test;import java.text.DecimalFormat;/*** @author 王楊帥* @create 2018-06-24 22:04* @desc**/ public class Case03 {/*** 實(shí)現(xiàn)類(lèi)實(shí)現(xiàn)*/@Testpublic void test01() {MyMoney myMoney = new MyMoney(99912333);MoneyFormatImpl moneyFormat = new MoneyFormatImpl();myMoney.printMoney(moneyFormat);}/*** 利用匿名內(nèi)部?jī)?nèi)實(shí)現(xiàn)*/@Testpublic void test02() {MyMoney myMoney = new MyMoney(9999999);myMoney.printMoney(new MoneyFormat() {@Overridepublic String format(int money) {return new DecimalFormat("#,###").format(money);}});}/*** lambda表達(dá)式實(shí)現(xiàn)*/@Testpublic void test03() {MyMoney myMoney = new MyMoney(999888888);myMoney.printMoney(money -> new DecimalFormat("#,###").format(money));}}/*** 自定義函數(shù)式接口*/ @FunctionalInterface interface MoneyFormat {String format(int money); }/*** 自定義類(lèi)*/ class MyMoney {private int money;/*** 有參構(gòu)造器* @param money*/public MyMoney(int money) {this.money = money;}/**** @param moneyFormat 自定義函數(shù)式接口類(lèi)型*/public void printMoney(MoneyFormat moneyFormat) {System.out.println("我的存款為:" + moneyFormat.format(this.money));} }class MoneyFormatImpl implements MoneyFormat {@Overridepublic String format(int money) {return new DecimalFormat("#,##").format(money);} } View Code

    3.3.3 改進(jìn)

      JDK1.8開(kāi)始提供了多個(gè)可供選擇的函數(shù)是接口,所以我們可以不用自己定義啦,選擇一個(gè)合適的拿過(guò)來(lái)用就可以啦

package a_test_demo;import org.junit.Test;import java.text.DecimalFormat; import java.util.function.Function;/*** @author 王楊帥* @create 2018-06-24 22:04* @desc**/ public class Case03 {/*** lambda表達(dá)式實(shí)現(xiàn)*/@Testpublic void test03() {MyMoney myMoney = new MyMoney(999888888);myMoney.printMoney(money -> new DecimalFormat("#,###").format(money));}@Testpublic void test04() {MyMoney myMoney = new MyMoney(8988888);Function<Integer, String> function = money -> new DecimalFormat("#,##").format(money);// 函數(shù)是接口的鏈?zhǔn)讲僮?/span>myMoney.printMoney(function.andThen(s -> {return "人民幣" + s;}));}}/*** 自定義類(lèi)*/ class MyMoney {private int money;/*** 有參構(gòu)造器* @param money*/public MyMoney(int money) {this.money = money;}/**** @param Function jdk1.8提供的函數(shù)接口*/public void printMoney(Function<Integer, String> function) {System.out.println("我的存款為:" + function.apply(this.money));} } View Code

?

4 lambda表達(dá)式的寫(xiě)法

  4.1 概念

    lambda表達(dá)式其實(shí)是實(shí)現(xiàn)了某個(gè)函數(shù)式接口的類(lèi)的一個(gè)實(shí)例;

    lambda表達(dá)式的箭頭左邊相當(dāng)于函數(shù)式接口中未實(shí)現(xiàn)方法的入?yún)?#xff0c;箭頭右邊相當(dāng)于函數(shù)式接口中未實(shí)現(xiàn)方法的函數(shù)體;

    lambda表達(dá)式就相當(dāng)于函數(shù)式接口中那個(gè)未實(shí)現(xiàn)的方法的實(shí)現(xiàn)而已。

    技巧01:編寫(xiě)Lambda 表達(dá)式,實(shí)際是編寫(xiě)函數(shù)式接口唯一的抽象方法的實(shí)現(xiàn)。因此,它是具備某種行為,或者說(shuō)是具備某種功能的代碼單元,這樣的功能代碼,可以傳遞給方法的參數(shù)。

    坑01:lambda 表達(dá)式是函數(shù)式接口的實(shí)現(xiàn)類(lèi)實(shí)例,所以,定義 lambda 表達(dá)式,實(shí)際上要經(jīng)歷兩件事情。第一件事情是定義函數(shù)式接口實(shí)現(xiàn)類(lèi),第二件事情是創(chuàng)建該實(shí)現(xiàn)類(lèi)實(shí)例。 this 稱(chēng)之為當(dāng)前對(duì)象,但是, 定義 lambda 表達(dá)式時(shí),也就是定義函數(shù)式接口實(shí)現(xiàn)類(lèi)時(shí), lambda 表達(dá)式代表的實(shí)現(xiàn)類(lèi)本身沒(méi)有 this 對(duì)象,此時(shí)若是使用 this 對(duì)象,指的是把 lambda 表達(dá)式圍住的類(lèi)的當(dāng)前對(duì)象,而不是 lambda 表達(dá)式代表的實(shí)現(xiàn)類(lèi)的當(dāng)前對(duì)象。(源自:gitchat)

    坑02:在lambda表達(dá)式使用了this關(guān)鍵字后,lambda表達(dá)式經(jīng)過(guò)編譯過(guò)后的方法就是一個(gè)靜態(tài)方法;沒(méi)有使用this關(guān)鍵字時(shí)編譯過(guò)后就是一個(gè)普通的成員方法。

package demo05_webflux.chapter02;/*** @author 王楊帥* @create 2018-07-29 9:28* @desc Lambda表達(dá)式的4中寫(xiě)法**/ public class Case04_LambdaDemo {public static void main(String[] args) {FuryInterface f1 = i -> i * 3;System.out.println(f1.result(20));System.out.println(f1.add(3, 44));FuryInterface f2 = (i) -> i * 3;FuryInterface f3 = (Integer i) -> i * 3;FuryInterface f4 = i -> {System.out.println("hello boy");return i * 3;};}}@FunctionalInterface interface FuryInterface {Integer result(Integer number);/*** Java8開(kāi)始可以利用default關(guān)鍵字在接口中定義已經(jīng)實(shí)現(xiàn)了的方法* @param a* @param b* @return*/default Integer add (Integer a, Integer b) {return a + b;} }/*** notes:* 1 函數(shù)式接口* 1.1 只有一個(gè)為實(shí)現(xiàn)方法的接口稱(chēng)為函數(shù)式接口* 1.2 函數(shù)式接口也可以被實(shí)現(xiàn),而且函數(shù)接口中的默認(rèn)方法和為實(shí)現(xiàn)的方法都可以被實(shí)現(xiàn)* 1.3 函數(shù)式接口中的默認(rèn)方法可以不在實(shí)現(xiàn)類(lèi)中實(shí)現(xiàn),但是函數(shù)式接口中的未實(shí)現(xiàn)方法必* 須在實(shí)現(xiàn)類(lèi)中進(jìn)行實(shí)現(xiàn)* 1.4 如果有兩個(gè)函數(shù)式接口的默認(rèn)方法一樣,有一個(gè)接口同時(shí)繼承了這兩個(gè)接口,那么必須在* 接口中指明繼承的式哪一個(gè)父接口中的默認(rèn)方法* 2 lambda表達(dá)式:* 2.1 lambda表達(dá)式其實(shí)是實(shí)現(xiàn)了某個(gè)函數(shù)式接口的類(lèi)的一個(gè)實(shí)例* 2.2 lambda表達(dá)式的箭頭左邊相當(dāng)于函數(shù)式接口中未實(shí)現(xiàn)方法的入?yún)?#xff0c;* 箭頭右邊相當(dāng)于函數(shù)式接口中未實(shí)現(xiàn)方法的函數(shù)體*/class test implements FuryInterface {@Overridepublic Integer result(Integer number) {return null;}@Overridepublic Integer add(Integer a, Integer b) {return null;} } View Code

?

?  

      

?

轉(zhuǎn)載于:https://www.cnblogs.com/NeverCtrl-C/p/9221300.html

總結(jié)

以上是生活随笔為你收集整理的Lambda01 编程范式、lambda表达式与匿名内部类、函数式接口、lambda表达式的写法...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。