八 JDK8新特性——第四節(jié) 方法引用-優(yōu)化Lambda

1违柏、方法引用基本介紹

主要對Lambda表達式的優(yōu)化
在使用Lambda表達式的時候为肮,實際上傳遞進去的是代碼就是一種解決方案,拿什么參數做什么需求涡真,那么考慮一種情況,如果我們在Lambda中所指的操作方案肾筐,已經有地方有相同方案哆料,是否需重復?

Lambda要有函數式接口吗铐,定義一個函數式接口

package com.company.demo05LambdaTest;

/**
 * @author 杜艷艷
 * @version 1.0
 * @date 2020/12/29 16:37
 * 定義一個打印的函數式接口,
 */
@FunctionalInterface
public interface Printable {
    //打印字符串的抽象方法
     void print(String s);
}

定義一個類剧劝。

package com.company.demo05LambdaTest;

/**
 * @author 杜艷艷
 * @version 1.0
 * @date 2020/12/29 16:39
 */
public class Demo01Printable {
    //定義一個方法,參數傳printable接口抓歼。對字符串打印
    public static void printString(Printable p ){
        p.print("helloword");
    }

    public static void main(String[] args) {
        //調用printstring方法 ,參數Printable是一個函數式接口讥此,可以傳遞lambda表達式
        printString((s)->{
            System.out.println(s); //helloword
        });
        /*
 分析
        lambda 表達式的目的,打印參數傳遞的字符串谣妻,把參數s傳遞給System.out對象萄喳,調用out對象的方法println,對字符串輸出
        注意:
        1蹋半、System.out對象已經存在他巨,
        2、調用其方法println已經存在

       所以可以用方法引用優(yōu)化lambda
       可以使用System.out直接引用(調用)println方法 ,取代Lambda染突, 對字符串輸出捻爷,參數省略
       :: 是方法引用的運算符,表達式是方法引用表達式
       兩種寫法效果一樣份企,第二種更簡潔
       注意:
       Lambda中傳遞的參數一定是方法引用中的那個方法可以接收的類型也榄,否則拋異常
         */
        printString(System.out::println);  //helloword
    }
}
方法引用符

2、方法引用-通過對象名引用成員方法

前提: 類存在司志,靜態(tài)方法存在

1甜紫、對象名要有實例 化的對象,所以要建一個類骂远,實例對象囚霸, 類中定義一個成員方法, 通過類創(chuàng)建一個對象激才,來引用里面的成員方法
類MethodRerObject

package com.company.demo06ObjectMethod;

/**
 * @author 杜艷艷
 * @version 1.0
 * @date 2020/12/30 16:48
 */
public class MethodRerObject {

    //定義一個成員方法拓型,傳遞字符串,按照大寫輸出
    public  void printUpString(String str){
        System.out.println(str.toUpperCase());
    }
}

2瘸恼、函數式接口

package com.company.demo06ObjectMethod;

/**
 * @author 杜艷艷
 * @version 1.0
 * @date 2020/12/29 16:37
 * 定義一個打印的函數式接口,
 */
@FunctionalInterface
public interface Printable {
    //打印字符串的抽象方法
     void print(String s);
}

3吨述、測試類

package com.company.demo06ObjectMethod;

/**
 * @author 杜艷艷
 * @version 1.0
 * @date 2020/12/30 16:51
 * 通過對象名引用成員方法
 * 使用前提:對象名存在,成員方法存在钞脂,就可以使用對象名引用成員方法
 */
public class Demo01ObjectMethodRer {
    //定義一個方法揣云。方法的參數傳遞Printable接口
    public static void printString(Printable p){
        p.print("hello");
    }

    public static void main(String[] args) {
        //調用printString ,方法的參數是函數式接口,可以傳遞lambda 表達式
        printString((s)->{
            //創(chuàng)建MethodRerObject對象
            MethodRerObject obj = new MethodRerObject();
            //調用對象中的成員方法printUpString冰啃,把字符串按照大寫輸出
            obj.printUpString(s);  //HELLO
        });

        /*使用方法引用優(yōu)化lambda
        對象MethodRerObject已經存在邓夕, 成員方法也存在printUpString
        所以可以用對象名來引用成員方法
         */
        //創(chuàng)建MethodRerObject對象
        MethodRerObject obj2 = new MethodRerObject();
        printString(obj2::printUpString);  //HELLO
    }
}

3、方法引用-通過類名引用靜態(tài)成員方法

由于在類中java.lang.Math中已經存在了靜態(tài)方法abs阎毅,所以需要通過lambda 調用該方法時焚刚,有兩種寫法,首先是函數式接口扇调,使用lambda 矿咕, 一種是類名引用靜態(tài)方法

函數式接口

package com.company.demo07StaticMethod;

/**
 * @author 杜艷艷
 * @version 1.0
 * @date 2020/12/30 17:08
 */
@FunctionalInterface
public interface Calcable {
    //定義一個抽象方法,傳遞一個整數狼钮,對整數進行絕對值計算碳柱,并返回
    public int calAbs(int number);
}

測試類

package com.company.demo07StaticMethod;

/**
 * @author 杜艷艷
 * @version 1.0
 * @date 2020/12/30 17:11
 * 通過類名引用靜態(tài)成員方法,使用前提:類名存在熬芜,靜態(tài)成員方法存在莲镣;就可以直接用類名引用靜態(tài)成員方法
 */
public class Demo01StaticMethodRer {
   //定義一個方法,方法的參數傳遞要計算絕對值的整數 和 函數式接口Calcable
    public static int method(int number,Calcable c){
        return c.calAbs(number);
    }

    public static void main(String[] args) {
        //調用method 方法涎拉,傳遞計算絕對值的整數 和 Lambda表達式
        int num = method(-10,(n)->{
            //對參數進行絕對值的計算瑞侮,并返回結果
            return Math.abs(n);
        });
        System.out.println(num);  //10

        /*通過類名引用靜態(tài)成員方法的圆。優(yōu)化lambda表達式
        Math 存在。abs 計算絕對值的靜態(tài)成員方法存在
        所以可以直接通過類名引用靜態(tài)方法
         */
        int num2 = method(-10, Math::abs);
        System.out.println(num2);  //10

    }
}

4半火、方法引用-通過super引用父類的成員方法

如果存在繼承關系越妈,當Lambda中需要出現super調用時,也可以使用方法引用進行替代
前提: 有子父類繼承關系钮糖,有函數式接口梅掠,父類有成員方法


例子

函數式接口

package con.day13.demo05.SuperMethodReference;

/*
定義一個見面的函數式接口
 */
@FunctionalInterface
public interface Greetable {
   //定義一個見面的方法
    void greet();
}

父類

package con.day13.demo05.SuperMethodReference;

/*
定義父類
 */
public class Human {
    //定義一個sayhello 的方法
    public void sayHello(){
        System.out.println("父類human的sayHellO");
    }
}

子類以及主方法

package con.day13.demo05.SuperMethodReference;
/*
定義子類
 */
public class Man extends Human{
    //重寫父類sayHello的方法

    @Override
    public void sayHello() {
        System.out.println("我是子類");
    }

    //定義一個方法參數傳遞Greetable接口
    public void method(Greetable g){
        g.greet();
    }

    public void show(){
        //調用method 方法,方法的參數是函數式接口藐鹤,可傳遞Lambda
       /* method(()->{
            //創(chuàng)建父類對象
            Human h = new Human();
            //調用父類的sayHello
            h.sayHello();
        });*/
        //因為有子父類關系,可以存在一個關鍵字super 所以我們可以直接用super調用父類的成員方法

       /* method(()->{
            super.sayHello();    //父類human的sayHellO
        });*/

        //繼續(xù)簡化赂韵, 使用super引用父類的成員方法娱节, super 已經存在,sayHello 已經存在祭示,
        //所以可直接使用super引用父類的成員方法
        //父類human的sayHellO
        method(super::sayHello);
    }

    public static void main(String[] args) {
        new Man().show();  //父類human的sayHellO
    }
}

5肄满、方法引用,通過this引用本類的成員

this

函數式接口

package con.day13.demo05.ThisMethodReference;

/*
定義一個函數式接口
 */
@FunctionalInterface
    public interface Richable {
        //想買什么就買什么的方法
        void buy();
    }

方法:

package con.day13.demo05.ThisMethodReference;

/*
通過this引用本類的成員方法
 */
public class Husband {
    //定義一個買房子的方法
    public void buyHouse(){
        System.out.println("買到房子啦");
    }
    //定義結婚方法质涛,參數傳遞Richable接口
    public void marry(Richable r){
        r.buy();
    }

/*    //定義一個非常高興的方法
    public void soHappy(){
        //調用結婚方法稠歉。方法的參數Richable 是一個函數式接口,用Lambda
        marry(()->{
            //使用this.成員方法汇陆,調用本類買房子的方法
            this.buyHouse();  //買到房子啦
        });
    }*/

    //簡化怒炸, 方法引用

    //定義一個非常高興的方法
    public void soHappy(){
        //調用結婚方法。方法的參數Richable 是一個函數式接口毡代,用Lambda
        marry(this::buyHouse);  //買到房子啦;
    }


    public static void main(String[] args) {
        Husband husband = new Husband();
        husband.soHappy();
    }
}

6阅羹、 方法引用-類的構造器引用

Person 類

package con.day13.demo05.ConstructorMethodReference;

public class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public Person() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

函數式接口

package con.day13.demo05.ConstructorMethodReference;
//創(chuàng)建Perso對象的函數式接口
@FunctionalInterface
public interface PersonBuilder {
    //定義一個方法,根據傳遞的姓名教寂,創(chuàng)建Person 對象返回
    Person builderPerson(String name);
}

方法類

package con.day13.demo05.ConstructorMethodReference;

/*
類的構造器引用
 */
public class Demo {
    //定義一個方法捏鱼,參數傳遞姓名和PersonBuilder接口,方法中通過姓名創(chuàng)建Person對象
    public static void pringName(String name, PersonBuilder pb){
        Person person = pb.builderPerson(name);
        System.out.println(person.getName()); //迪麗熱巴
    }

/*    public static void main(String[] args) {
        //調用pringName方法酪耕,方法的參數是PersonBuilder 导梆,函數式接口,用Lambda
        pringName("迪麗熱巴",(String name)->{
            return new Person(name);
        });
    }*/
/*使用方法引用迂烁,優(yōu)化
構造方法new Person(String name)已知
創(chuàng)建對象已經new
就可以使用Person引用new創(chuàng)建對象
    */
    public static void main(String[] args) {
        //調用pringName方法看尼,方法的參數是PersonBuilder ,函數式接口盟步,用Lambda
        pringName("迪麗熱巴", Person::new);
    }
}

7狡忙、方法引用-數組的構造引用

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市址芯,隨后出現的幾起案子灾茁,更是在濱河造成了極大的恐慌窜觉,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件北专,死亡現場離奇詭異禀挫,居然都是意外死亡,警方通過查閱死者的電腦和手機拓颓,發(fā)現死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門语婴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人驶睦,你說我怎么就攤上這事砰左。” “怎么了场航?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵缠导,是天一觀的道長。 經常有香客問我溉痢,道長僻造,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任孩饼,我火速辦了婚禮髓削,結果婚禮上,老公的妹妹穿的比我還像新娘镀娶。我一直安慰自己立膛,他們只是感情好,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布梯码。 她就那樣靜靜地躺著旧巾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪忍些。 梳的紋絲不亂的頭發(fā)上鲁猩,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天,我揣著相機與錄音罢坝,去河邊找鬼廓握。 笑死物赶,一個胖子當著我的面吹牛偿枕,可吹牛的內容都是我干的。 我是一名探鬼主播唉俗,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼闹司,長吁一口氣:“原來是場噩夢啊……” “哼娱仔!你這毒婦竟也來了?” 一聲冷哼從身側響起游桩,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤牲迫,失蹤者是張志新(化名)和其女友劉穎耐朴,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體盹憎,經...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡筛峭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了陪每。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片影晓。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖檩禾,靈堂內的尸體忽然破棺而出挂签,到底是詐尸還是另有隱情,我是刑警寧澤盼产,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布饵婆,位于F島的核電站,受9級特大地震影響辆飘,放射性物質發(fā)生泄漏啦辐。R本人自食惡果不足惜谓传,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一蜈项、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧续挟,春花似錦紧卒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至直颅,卻和暖如春博个,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背功偿。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工盆佣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人械荷。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓共耍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親吨瞎。 傳聞我的和親對象是個殘疾皇子痹兜,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內容