成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

樂字節(jié)-Java8核心特性實戰(zhàn)之Lambda表達式

Karuru / 1171人閱讀

摘要:使用表達式,使得應(yīng)用變得簡潔而緊湊。很多語言等從設(shè)計之初就支持表達式。表達式的參數(shù)與函數(shù)式接口內(nèi)方法的參數(shù),返回值類型相互對應(yīng)。更多教程和資料請上騰訊課堂樂字節(jié)

Java8 引入Lambda表達式,允許開發(fā)者將函數(shù)當成參數(shù)傳遞給某個方法,或者把代碼本身當作數(shù)據(jù)進行處理。使用Lambda表達式,使得應(yīng)用變得簡潔而緊湊。 很多語言(Groovy、Scala等)從設(shè)計之初就支持Lambda表達式。但是java中使用的是 匿名內(nèi)部類代替。最后借助強大的社區(qū)力量,找了一個折中的Lambda實現(xiàn)方案,可以實現(xiàn)簡潔而緊湊的語言結(jié)構(gòu)。

一、匿名內(nèi)部類到Lambda的演化

匿名內(nèi)部類,即一個沒有名字的,存在于一個類或方法內(nèi)部的類。當我們需要用某個類且只需要用一次,創(chuàng)建和使用和二為一時,我們可以選擇匿名內(nèi)部類,省掉我們定義類的步驟。

匿名內(nèi)部類會隱士的繼承一個類或?qū)崿F(xiàn)一個接口,或者說匿名內(nèi)部類是一個繼承了該類或者實現(xiàn)了該接口的子類匿名對象。下面看一個匿名內(nèi)部類的例子

package com.java8;
/*
    定義和使用匿名內(nèi)部類
 */
public class NoNameClass {
    public static void main(String[] args) {

        Model m = new Model(){
            @Override
            public void func() {
                System.out.println("方法的實現(xiàn)");
            }
        };
        m.func();
    }
}
// 需要被實現(xiàn)的接口
interface Model{
    void func();
}

等價的Lambda 代碼

package com.java8;
/*
    定義和使用Lambda 簡化代碼
 */
public class NoNameClass {
    public static void main(String[] args) {

        Model m = new Model(){()->{
            System.out.println("方法的實現(xiàn)");
        }};
        m.func();
    }
}

可以看出使用Lambda 表達式替代了匿名內(nèi)部類代碼,使得代碼更加簡化、緊湊。

1、語法

(parameters) -> expression? 或 ?(parameters) ->{ statements; }  

可選類型聲明
不需要聲明參數(shù)類型,編譯器可以統(tǒng)一識別參數(shù)值。

可選的參數(shù)圓括號
一個參數(shù)無需定義圓括號,但多個參數(shù)需要定義圓括號。

可選的大括號
如果主體包含了一個語句,就不需要使用大括號。

可選的返回關(guān)鍵字
如果主體只有一個表達式返回值則編譯器會自動返回值,大括號需要指明表達式返回了一個數(shù)值

2、Lambda 表達式示例

二、Lambda使用形式

使用Lambda時,實現(xiàn)方法可以有參數(shù),也可以有返回值,如果沒指定參數(shù)類型,則由編譯器自行推斷得出。

1、無參帶返回值

生成[1,10]之間的任意整數(shù)

interface Model2{
    int func();
}
Model2 md2 = () -> {return (int)(Math.random()*10+1)};

Lambda的改寫需要有對應(yīng)的抽象方法,當沒有參數(shù)時需要使用()占位,當表達式只有一行代碼時,可以省略return和{}

以上的Lambda等價于:

Model2 md2 = () -> (int)(Math.random()*10+1);
2、帶參帶返回值

返回一個對數(shù)字描述的字符串。

interface Model3{
    String func(int a);
}
Model3 md3 = (int a) -> {
    return "This is a number " + a;
};

形參寫在()內(nèi)即可,參數(shù)的類型可以省略,此時將由編譯器自行推斷得出,同時還可以省略()

以上的Lambda等價于:

md3 =  a -> "This is a number " + a;

省略了參數(shù)類型,小括號,同時連帶實現(xiàn)體的括號和return一并省去。

3、帶多個參數(shù)

根據(jù)輸入的運算符計算兩個數(shù)的運算,并返回結(jié)果

interface Model4{
    String func(int a, int b, String oper);
}
 Model4 md4 = (a, b, s) -> {
      String res = "";
      if("+".equals(s)){
            res = ( a+b ) + "";
      }else if("-".equals(s)){
            res = ( a-b ) + "";
      }else if("*".equals(s)){
            res = ( a*b ) + "";
      }else if("/".equals(s)){
            res = ( a/b ) + ""; // 暫不考慮除0的情況
      }else{
            res =  "操作有失誤";
      }
      return res;
 };
 System.out.println(md4.func(1,1,"+"));

以上例子為多個參數(shù)的Lambda表達式,其中省略掉了每一個參數(shù)的類型,編譯器自動推斷。多條語句時實現(xiàn)體的{}不能省。
三、Lambda作為參數(shù)

在Java8之前,接口可以作為方法參數(shù)傳入,執(zhí)行時必須提供接口實現(xiàn)類的實例。從java8開始,Lambda可以作為接口方法實現(xiàn),當作參數(shù)傳入,無論從形式上還是實際上都省去了對象的創(chuàng)建。使代碼更加的緊湊簡單高效。

1、定義接口

在接口中,必須有且僅有一個抽象方法,以確定Lambda模板

// 無參無返回值的方法
interface LambdaInterface1{
    void printString();
}
// 帶參無返回值的方法
interface  LambdaInterface2{
    void printString(String str);
}
2、定義方法接收參數(shù)

在某方法中需要使用接口作為參數(shù)

  // 無參
  public static void testLambda(LambdaInterface1 lam1){
    lam1.printString();
  }
  // 帶參
  public static void testLambda2(String s,LambdaInterface2 lam2){
    lam2.printString(s);
  }
3、Lambda表達式作為參數(shù)傳入
// 無參Lambda作為參數(shù)
testLambda(()->{
    System.out.println("可以簡單,可以復(fù)雜");
});
// 帶參Lambda作為參數(shù)
testLambdaParam("hello",(a)->{
    System.out.println(a);
});
四、Lambda中使用變量

在Lambda中可以定義自己的局部變量,也可以使用外層方法的局部變量,還可以使用屬性。這一點也不難理解,既然是一個方法的實現(xiàn),只寫了一個代碼塊,那么使用本身所屬方法的局部變量和類的屬性也并不過分。

public static void main(String[] args) {
    List strs = new ArrayList(){
        {
            add("aaa");
            add("bbb");
            add("ccc");
        }
    };
    int j = 1;
    strs.forEach((str)->{
        int i = 0;
        System.out.println(str + "  " + i + "  " + j);
    });
}
五、Lambda類型推斷 1、類型檢查

Lambda的類型是從使用Lambda的上下文推斷出來的。 Lambda表達式的參數(shù)與函數(shù)式接口內(nèi)方法的參數(shù),返回值類型相互對應(yīng)。Lambda表達式需要的類型,或者說Lambda實現(xiàn)的那個函數(shù)式接口稱之為目標類型。

2、類型推斷

利用目標類型來檢查一個Lambda是否可以用于某個特定的上下文,推斷Lambda參數(shù)的類型。

六、Lambda表達式實戰(zhàn)

熱銷商品排序

排序?qū)τ诰媒?jīng)開發(fā)的你來說可能并不陌生,假如原來你做過電商項目,相信對于電商場景下的商品記錄排序操作很有感情,下面我們使用Lambda 來看看熱銷商品排序的操作。

測試數(shù)據(jù)這里以手機測試數(shù)據(jù)為例

/**
* 實際開發(fā)數(shù)據(jù)通常從數(shù)據(jù)庫獲取
* 這里使用測試數(shù)據(jù)
*/
Goods g01=new Goods(1,"小米9",1789,200, BigDecimal.valueOf(2500));
Goods g02=new Goods(2,"華為Mate20",5000,3000, BigDecimal.valueOf(7000));
Goods g03=new Goods(3,"OPPO R17",2000,2827, BigDecimal.valueOf(1500));
Goods g04=new Goods(4,"魅族 Note9",2000,1600, BigDecimal.valueOf(1600));
Goods g05=new Goods(5,"一加6T",8000,5000, BigDecimal.valueOf(3500));
List goods= Arrays.asList(g01,g02,g03,g04,g05);

Collections.sort 靜態(tài)方法實現(xiàn)排序

Collections.sort(goods,(g1,g2)->g1.getSale()-g2.getSale());

List.sort 默認方法實現(xiàn)集合排序

// 使用Lambda 對商品記錄按銷量進行排序
goods.sort((g1,g2)->g1.getSale()-g2.getSale());

Stream.sorted 方法實現(xiàn)元素排序

// 多個條件排序情況 Lambda 配置Stream 銷量+價格排序 銷量相等時按照價格排序
goods =goods.stream().sorted((g1,g2)->g1.getSale()-g2.getSale())
.sorted((g1,g2)->g1.getPrice().compareTo(g2.getPrice()))
.collect(Collectors.toList());

日志輸出優(yōu)化

?????? 對于項目開發(fā)日志打印是一項不可獲取的模塊,無論實在開發(fā)階段還是項目部署上線后,日志信息的輸出對于開發(fā)人員來以及運維人員來說都是一項重要的參考指標。

日志輸出場景這里以用戶模塊UserService 為例,以下為優(yōu)化前的日志輸出代碼:

public String login(String userName, String userPwd) {
    logger.info("UserService 接收到參數(shù)-->" + userName + "," + userPwd);
    /**
     * 登錄邏輯省略
     */
    return "login";
}

日志級別設(shè)置到debug,在開發(fā)階段方便查看后端接收到的參數(shù)信息。仔細分析這里的日志代碼,可以看到當日志級別設(shè)置為info 時 debug 日志不應(yīng)該執(zhí)行輸出操作,同時這里調(diào)用debug 方法時,對于傳入的字符串參數(shù)需要作對應(yīng)的拼接操作,才會傳入過來。當訪問的情況在商城項目做活動情況下 這里的情況有可能會變得很糟糕:所有的debug 信息全部輸出 同時會有大量字符串拼接操作,會影響整個應(yīng)用程序的執(zhí)行性能。 

日志輸出場景這里以用戶模塊UserService 為例,日志輸出代碼優(yōu)化

輸出日志前判斷日志輸出級別

借助Lambda延遲日志內(nèi)容輸出

/**

添加info方法

判斷日志打印級別

當條件成立時 輸出日志信息

@param logger

@param message

 */
public   void info(Log logger, Supplier message){
    if(logger.isInfoEnabled()){
        logger.info(message.get());
    }
}

public String login(String userName, String userPwd) {
    //logger.info("UserService 接收到參數(shù)-->" + userName + "," + userPwd);
    // 延遲Lambda 表達式執(zhí)行  只有確定
    info(logger,()->"UserService 接收到參數(shù)-->" + userName + "," + userPwd);
    return "login";
}

Lambda優(yōu)勢與使用場景

Lambda表達式的引入取代了匿名內(nèi)部類,使得代碼變得簡潔、緊湊,同時Lambda的惰性特點,在開發(fā)時能夠提高應(yīng)用程序的執(zhí)行性能。

對于Lambda的應(yīng)用場景,從代碼結(jié)構(gòu)來說通常是結(jié)合函數(shù)式接口來使用,使得開發(fā)是面向函數(shù)來進行編程,也是Java8引入的一種新的思想-函數(shù)式編程(后續(xù)會介紹)。同時還會結(jié)合前面講到的接口默認方法提現(xiàn)到應(yīng)用開發(fā)中。

樂字節(jié)原創(chuàng),轉(zhuǎn)載請注明出處和作者。
更多教程和資料請上 騰訊課堂:樂字節(jié)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/74739.html

相關(guān)文章

  • 字節(jié)Java8核心特性實戰(zhàn)方法引用

    摘要:大家好,我是樂字節(jié)的小樂,上一次我們說到了核心特性之函數(shù)式接口,接下來我們繼續(xù)了解又一核心特性方法引用。方法引用是一種更簡潔易懂的表達式。感謝光臨閱讀小樂的,敬請關(guān)注樂字節(jié)后續(xù)將繼續(xù)講述等前沿知識技術(shù)。 大家好,我是樂字節(jié)的小樂,上一次我們說到了Java8核心特性之函數(shù)式接口,接下來我們繼續(xù)了解Java8又一核心特性——方法引用。 showImg(https://segmentfaul...

    lakeside 評論0 收藏0
  • 字節(jié)-Java8核心特性實戰(zhàn)函數(shù)式接口

    摘要:大家好,上一篇小樂給大家講述了樂字節(jié)核心特性表達式,點擊回顧。接下來繼續(xù)核心特性之函數(shù)式接口。感謝大家欣賞小樂帶來的核心特性之函數(shù)式接口,接下來還會更多核心技術(shù)講解,請關(guān)注樂字節(jié)如需要視頻課程,請搜索樂字節(jié)騰訊課堂 大家好,上一篇小樂給大家講述了《樂字節(jié)-Java8核心特性-Lambda表達式》,點擊回顧。接下來繼續(xù):Java8核心特性之函數(shù)式接口。 什么時候可以使用Lambda?通常...

    niceforbear 評論0 收藏0
  • 字節(jié)-Java8核心特性實戰(zhàn)-接口默認方法

    摘要:語法中接口可以包含實現(xiàn)方法,需要使用修飾,此類方法稱為默認方法。核心特性接口默認方法就介紹到這里了,后續(xù)小樂會繼續(xù)講述核心特性。 JAVA8已經(jīng)發(fā)布很久,是自java5(2004年發(fā)布)之后Oracle發(fā)布的最重要的一個版本。其中包括語言、編譯器、庫、工具和JVM等諸多方面的新特性,對于國內(nèi)外互聯(lián)網(wǎng)公司來說,Java8是以后技術(shù)開發(fā)的趨勢。這里主要講解在開發(fā)中幾個核心的新特性。(主要從...

    lbool 評論0 收藏0
  • 字節(jié)-Java8特性方法引用

    摘要:上一篇小樂介紹了新特性函數(shù)式接口,大家可以點擊回顧。中引入方法引用新特性用于簡化應(yīng)用對象方法的調(diào)用,方法引用是用來直接訪問類或者實例的已經(jīng)存在的方法或者構(gòu)造方法。方法引用是一種更簡潔易懂的表達式。 上一篇小樂介紹了《Java8新特性-函數(shù)式接口》,大家可以點擊回顧。這篇文章將接著介紹Java8新特性之方法引用。 Java8 中引入方法引用新特性,用于簡化應(yīng)用對象方法的調(diào)用,?方法引用是...

    Codeing_ls 評論0 收藏0
  • 字節(jié)-Java8核心特性實戰(zhàn)Stream(流)

    摘要:大家好,我是樂字節(jié)的小樂。需要注意的是很多流操作本身就會返回一個流,所以多個操作可以直接連接起來,如下圖這樣,操作可以進行鏈式調(diào)用,并且并行流還可以實現(xiàn)數(shù)據(jù)流并行處理操作。為集合創(chuàng)建并行流。 大家好,我是樂字節(jié)的小樂。說起流,我們會聯(lián)想到手機、電腦組裝流水線,物流倉庫商品包裝流水線等等,如果把手機 ,電腦,包裹看做最終結(jié)果的話,那么加工商品前的各種零部件就可以看做數(shù)據(jù)源,而中間一系列的...

    wenshi11019 評論0 收藏0

發(fā)表評論

0條評論

Karuru

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<