Java中 lambda表達(dá)式

lambda表達(dá)式

一丢氢、什么是lambda表達(dá)式

lambda是接口的一種實(shí)現(xiàn)方式拷淘,是JDK 1.8的新特性

二、怎么使用lambda表達(dá)式

2.1 接口的使用過程

第一步:定義接口

第二步:接口實(shí)現(xiàn)

第三步:接口使用

2.2 lambda實(shí)現(xiàn)接口

接口定義

public interface IMathOperation {
    int add(int x,int y);
}//接口的定義

接口的實(shí)現(xiàn)和使用

public class Test {
    public static void main(String[] args) {
        //接口的實(shí)現(xiàn) 使用lambda表達(dá)式
        IMathOperation im = (x,y)->{
            return x+y;
        };
        //接口的使用
        System.out.println(im.add(5, 6));
    }
}

2.3 lambda表達(dá)式的寫法

語法:(參數(shù))->{方法體}

情況一:只有一個(gè)參數(shù)

public interface IMathOperation {
    void add(int x);
}
class Test1{
    public static void main(String[] args) {
        IMathOperation im = (x) -> {
            System.out.println(x);
        };
        // x ->System.out.println(x);可以省略()以及{},但都不推薦
        im.add(5);
    }
}

只有一個(gè)參數(shù)時(shí),()可以省略识椰,不推薦省略。

方法實(shí)現(xiàn)只有一行代碼時(shí)深碱,可以省略{}腹鹉,不推薦省略。

情況二:有多個(gè)參數(shù)

public interface IMathOperation {
    void add(int x,int y);
}
class Test1{
    public static void main(String[] args) {
        IMathOperation im = (x,y) -> {
            System.out.println(x+y);
        };
        im.add(5,9);
    }
}

情況三:沒有參數(shù)

public interface IMathOperation {
    void add();
}
class Test1{
    public static void main(String[] args) {
        IMathOperation im = () -> {
            System.out.println("沒有參數(shù)");
        };
        im.add();
    }
}

在方法實(shí)現(xiàn)中沒有代碼時(shí)敷硅,要寫上{}空方法體

IMathOperation im = () -> { };
im.add();

2.4 lambda表達(dá)式的特征

  • 可選的類型聲明:不需要聲明參數(shù)類型功咒,編譯器可以自動(dòng)識(shí)別參數(shù)類型。
  • 可選的參數(shù)圓括號(hào):一個(gè)參數(shù)無需使用圓括號(hào)绞蹦,只要不是一個(gè)參數(shù)則需要使用圓括號(hào)力奋。
  • 可選的花括號(hào):如果函數(shù)體只有一條語句,則不需要使用花括號(hào)幽七。

2.5 lambda的限制條件

lambda表達(dá)式在實(shí)現(xiàn)接口時(shí)景殷,接口只允許有且只有一個(gè)抽象方法。

這種限制可以使用函數(shù)式接口來定義

三锉走、函數(shù)式接口

3.1 什么是函數(shù)式接口

函數(shù)式接口(@FunctionalInterface):

Lambda表達(dá)式相當(dāng)于對(duì)接口中的方法給出了實(shí)現(xiàn)滨彻,如果在接口中聲明了多個(gè)抽象方法,那么Lambda表達(dá)式實(shí)現(xiàn)的是哪個(gè)方法呢挪蹭?無法確定亭饵,因此要求Lambda表達(dá)式實(shí)現(xiàn)的接口只能有一個(gè)抽象的方法,這樣的接口稱為函數(shù)式接口梁厉。

為了避免接口中出現(xiàn)多個(gè)抽象方法辜羊,可以在接口上使用`@FunctionalInterface`注解,聲明該接口是一個(gè)函數(shù)式接口词顾,例如:
@FunctionalInterface
public interface IMathOperation {
    void add();
}

如果在接口中聲明了另外的抽象方法八秃,那么在編譯的時(shí)候,編譯器就會(huì)提示錯(cuò)誤肉盹。

@FunctionalInterface//報(bào)錯(cuò)了昔驱,這個(gè)接口有兩個(gè)抽象方法
public interface IMathOperation {
    void add();
    void show();//添加一個(gè)抽象方法
}

Multiple non-overriding abstract methods found in interface IMathOperation

3.2 內(nèi)置函數(shù)式接口

內(nèi)置函數(shù)式接口:幫我們定義了接口,我們無需再自己定義接口了

既然Lambda表達(dá)式需要配合函數(shù)式接口來使用上忍,且在函數(shù)式接口中只有一個(gè)抽象方法骤肛,那么完全可以針對(duì)方法的參數(shù)個(gè)數(shù),以及是否有返回值窍蓝,來定義一些常用的函數(shù)式接口腋颠。至于參數(shù)類型和返回值類型,則可以使用泛型來表示吓笙。

其實(shí)我們的Lambda表達(dá)式就是對(duì)函數(shù)式接口的一種簡寫方式淑玫,所以只有是函數(shù)式接口,我們才能用Lambda表達(dá)式;再換句話說絮蒿,Lambda表達(dá)式需要函數(shù)式接口的支持尊搬,那函數(shù)式接口我們可以自己定義,當(dāng)然JDK1.8也給我們提供了一些現(xiàn)成的函數(shù)式接口土涝;

Java 8在java.util.function包中毁嗦,定義了許多函數(shù)式接口回铛,下表列出了四個(gè)基本的函數(shù)式接口。

函數(shù)式接口 方法 用途
Consumer< T > void accept(T t) 消費(fèi)性接口 (有來無回)克锣,即有參數(shù)沒有返回值
Predicate< T > boolean test(T t) Asset段言型茵肃,有參數(shù),返回值為boolean類型
Function< T,R > R apply(T t) 函數(shù)型接口袭祟,有參數(shù)有返回值验残,皆為任意類型
Supplier T get() 供給型接口,無參數(shù)巾乳,有返回值

例如

  • Consumer< T >
class Test1{
    public static void main(String[] args) {
        Consumer<String> im = (s) -> {
            System.out.println(s);
        };
        im.accept("Consumer");
    }
}
  • Predicate< T >
class Test1{
    public static void main(String[] args) {
        Predicate<String> im = (s) -> {
            if (s.equals("芝麻開門")){
                System.out.println("密碼正確");
                return true;
            }else {
                return false;
            }
        };
        im.test("芝麻開門");
    }
}
  • Function< T,R >
class Test1{
    public static void main(String[] args) {
        Function<Integer,String> im = (x) -> {
            return x>0?"正確":"錯(cuò)誤";
        };
        System.out.println(im.apply(10));
    }
}
  • Supplier
class Test1{
    public static void main(String[] args) {
        Supplier im = () -> {
            return "很久很久以前您没,巨龍突然出現(xiàn)";
        };
        System.out.println(im.get());
    }
}

四、方法引用

方法引用:幫我們完成了接口實(shí)現(xiàn)胆绊,省去了我們自己定義Lambda表達(dá)式

如果一個(gè)類中的實(shí)現(xiàn)方法氨鹏,其參數(shù)列表和返回值類型與某個(gè)函數(shù)式接口中的方法一致,那么可以使用方法引用的方式來代替Lambda表達(dá)式压状。Java編譯器會(huì)利用函數(shù)式接口中方法的參數(shù)來調(diào)用引用的方法仆抵,并將該方法的返回值(如果有的話)作為接口方法的返回值。
方法引用使用操作符“::”將對(duì)象或者類的名字與方法名分隔開。主要有以下三種形式:

● 對(duì)象::實(shí)例方法名
● 類名::靜態(tài)方法名
● 對(duì)象::靜態(tài)方法名

class Test1{
    public static String getStr1(String str1){
        return str1;
    }
    public  String getStr2(String str2){
        return str2;
    }
    public static void main(String[] args) {
        Function<String,String> fun = (str) -> {
            return "很久很久以前\n巨龍突然出現(xiàn)\n"+str;
        };
        System.out.println(fun.apply("帶來災(zāi)難\n" +"帶走了公主又消失不見"));

        //類名::靜態(tài)方法名
        Function<String,String> fun1 = Test1::getStr1;
        System.out.println(fun1.apply("很久很久以前\n巨龍突然出現(xiàn)\n"));

        //對(duì)象::實(shí)例方法名
        Test1 test = new Test1();
        Function<String,String> fun2 = test::getStr2;
        System.out.println(fun2.apply("帶來災(zāi)難\n" + "帶走了公主又消失不見"));
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市十兢,隨后出現(xiàn)的幾起案子趣竣,更是在濱河造成了極大的恐慌,老刑警劉巖纪挎,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件期贫,死亡現(xiàn)場離奇詭異,居然都是意外死亡异袄,警方通過查閱死者的電腦和手機(jī)通砍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人迹冤,你說我怎么就攤上這事虎忌∨葆悖” “怎么了?”我有些...
    開封第一講書人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵膜蠢,是天一觀的道長堪藐。 經(jīng)常有香客問我,道長杉辙,這世上最難降的妖魔是什么模捂? 我笑而不...
    開封第一講書人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮蜘矢,結(jié)果婚禮上狂男,老公的妹妹穿的比我還像新娘。我一直安慰自己品腹,他們只是感情好岖食,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著珍昨,像睡著了一般县耽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上镣典,一...
    開封第一講書人閱讀 51,208評(píng)論 1 299
  • 那天兔毙,我揣著相機(jī)與錄音,去河邊找鬼兄春。 笑死澎剥,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的赶舆。 我是一名探鬼主播哑姚,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼芜茵!你這毒婦竟也來了叙量?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤九串,失蹤者是張志新(化名)和其女友劉穎绞佩,沒想到半個(gè)月后寺鸥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡品山,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年胆建,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肘交。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡笆载,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出涯呻,到底是詐尸還是另有隱情凉驻,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布复罐,位于F島的核電站沿侈,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏市栗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一咳短、第九天 我趴在偏房一處隱蔽的房頂上張望填帽。 院中可真熱鬧,春花似錦咙好、人聲如沸篡腌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嘹悼。三九已至,卻和暖如春层宫,著一層夾襖步出監(jiān)牢的瞬間杨伙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來泰國打工萌腿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留限匣,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓毁菱,卻偏偏與公主長得像米死,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子贮庞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容