【Java8新特性】04 詳解Lambda表達式中Predicate Function Consumer Supplier函數(shù)式接口

Java8 由Oracle在2014年發(fā)布吨拍,是繼Java5之后最具革命性的版本斧抱。

Java8吸收其他語言的精髓帶來了函數(shù)式編程,lambda表達式脂倦,Stream流等一系列新特性畅厢,學(xué)會了這些新特性冯痢,可以讓你實現(xiàn)高效編碼優(yōu)雅編碼。

函數(shù)式接口

函數(shù)式接口是指只定義了一個抽象方法的接口,不包括default默認方法系羞。

函數(shù)式接口的抽象方法的簽名稱為函數(shù)描述符郭计,通過函數(shù)描述符可以很好得到Lambda表達式的簽名。

常見的函數(shù)式接口有:Runnable, Callable, Comparator等椒振。除此之外昭伸,Java8設(shè)計者還新增了一些比較抽象的函數(shù)式接口,比如:Predicate, Consumer, Supplier, Function, UnaryOperator, BinaryOperator等, 這些函數(shù)式接口定義在java.util.function包中澎迎。

接下來詳細介紹function包中定義的抽象接口:

1. Predicate

(1)定義

Predicate是謂詞的意思庐杨,用來判斷泛型T對象是否符合條件,如果符合返回true夹供,否則返回false灵份。

查看jdk源碼,定義了一個抽象方法test:

@FunctionalInterfacepublicinterfacePredicate<T>{/**

? ? * Evaluates this predicate on the given argument.

? ? *

? ? * @param t the input argument

? ? * @return {@code true} if the input argument matches the predicate,

? ? * otherwise {@code false}

? ? */booleantest(T t);}

(2)使用方法

Predicate是一個接口所以不能直接實例化哮洽,可以使用匿名類或者Lambda表達式實例化填渠。以Lambda為例:

// 接收string對象,判斷是否為空鸟辅,返回booleanPredicate predicate=(String str)->str.isEmpty();

下面以一個校驗參數(shù)的實例說明:

@TestpublicvoidtestPredicate(){String input="hello java8";if(validate(input,(str)->!str.isEmpty()&&str.length()>5)){// 校驗輸入System.out.println("valid input");}}// 第二個參數(shù)接收一個Predicate實例private<T>booleanvalidate(T input,Predicate<T>predicate){returnpredicate.test(input);}

(3)函數(shù)描述符

Predicate: T -> boolean

接受泛型T對象返回boolean氛什。

注意:java.util.function包中還針對基本類型封裝了類似IntPredicate, LongPredicate等接口,這無非是表明只接受Int或Long類型的輸入匪凉,后面Consumer等函數(shù)式接口與這個類似枪眉,本文不再贅述。

2. Consumer

(1)定義

Consumer是消費者的意思再层,用來接收一個泛型T對象贸铜,執(zhí)行相關(guān)操作,最后返回void聂受。

查看jdk源碼蒿秦,定義了一個抽象方法accept:

@FunctionalInterfacepublicinterfaceConsumer<T>{/**

? ? * Performs this operation on the given argument.

? ? *

? ? * @param t the input argument

? ? */voidaccept(T t);}

(2)使用方法

使用Lambda表達式實例化Consumer接口:

Consumer<String>consumer=(str)->System.out.println(str);

下面以打印字符串的實例講解Consumer的用法:

@TestpublicvoidtestConsumer(){String input="hello java8";// 打印輸入consume(input,(str)->System.out.println(str));}private<T>voidconsume(T input,Consumer<T>consumer){consumer.accept(input);}

(3)函數(shù)描述符

Consumer: T -> void

接受泛型T對象返回void。

3. Supplier

(1)定義

Supplier是提供者的意思饺饭,用來生成泛型T對象渤早。

查看jdk源碼职车,定義了一個抽象方法get:

@FunctionalInterfacepublicinterfaceSupplier<T>{/**

? ? * Gets a result.

? ? *

? ? * @return a result

? ? */Tget();}

(2)使用方法

使用Lambda表達式實例化Supplier接口:

Supplier supplier=()->"Hello Java8 supplier";

下面以獲取當(dāng)前時間的實例講解Supplier的用法:

@TestpublicvoidtestSupplier(){// 獲取當(dāng)前時間Long currentTime=supply(()->System.currentTimeMillis());}private<T>Tsupply(Supplier<T>supplier){returnsupplier.get();}

(3)函數(shù)描述符

Supplier: void -> T

接受void返回泛型T對象瘫俊。

4. Function

(1)定義

Function是函數(shù)的意思,用來定義一個抽象函數(shù)悴灵,接收泛型T對象扛芽,返回泛型R對象。

查看jdk源碼积瞒,定義了一個抽象方法apply:

@FunctionalInterfacepublicinterfaceFunction<T,R>{/**

? ? * Applies this function to the given argument.

? ? *

? ? * @param t the function argument

? ? * @return the function result

? ? */Rapply(T t);}

(2)使用方法

使用Lambda表達式實例化Function接口:

Function<String,Integer>function=(str)->str.length();

下面以判斷輸入是否以指定字符串開頭的實例講解Function的用法:

@TestpublicvoidtestFunction(){String input="hello java8";if(func(input,(String str)->str.startsWith("hello"))){System.out.println("start with hello");}}private<T,R>Rfunc(T t,Function<T,R>function){returnfunction.apply(t);}

(3)函數(shù)描述符

Function: T -> R

接受泛型T對象川尖,返回泛型R對象。

5. UnaryOperator

(1)定義

UnaryOperator是一元操作符的意思茫孔,接收一個泛型T對象參數(shù)叮喳,返回相同T類型對象被芳。

查看jdk源碼,UnaryOperator繼承自Function接口馍悟,定義了一個identity方法:

@FunctionalInterfacepublicinterfaceUnaryOperator<T>extendsFunction<T,T>{/**

? ? * Returns a unary operator that always returns its input argument.

? ? *

? ? * @param <T> the type of the input and output of the operator

? ? * @return a unary operator that always returns its input argument

? ? */static<T>UnaryOperator<T>identity(){returnt->t;}}

(2)使用方法

使用Lambda表達式實例化UnaryOperator接口:

UnaryOperator<Integer>unaryOperator=(Integer i)->i*i;

下面以整數(shù)遞增的實例講解UnaryOperator的用法:

@TestpublicvoidtestUnaryOperator(){UnaryOperator<Integer>unaryOperator=(Integer i)->i*i;intinput=0;intresult=unaryOperate(input,(Integer i)->i+1);// output: 1System.out.println(result);}private<T>TunaryOperate(T t,UnaryOperator<T>unaryOperator){returnunaryOperator.apply(t);}

(3)函數(shù)描述符

UnaryOperator: T -> T

接受泛型T對象畔濒,返回泛型T對象。

6. BinaryOperator

(1)定義

BinaryOperator是二元操作符的意思锣咒,接收兩個相同泛型參數(shù)類型T侵状,返回R類型對象。

查看jdk源碼毅整,BinaryOperator繼承自BiFunction接口趣兄,繼承了BiFunction的apply方法:

@FunctionalInterfacepublicinterfaceBinaryOperator<T>extendsBiFunction<T,T,T>{/**

? ? * Applies this function to the given arguments.

? ? *

? ? * @param t the first function argument

? ? * @param u the second function argument

? ? * @return the function result

? ? */Rapply(T t,U u);}

(2)使用方法

使用Lambda表達式實例化BinaryOperator接口:

BinaryOperator<String>binaryOperator=(String str1,String str2)->str1+str2;

下面以整數(shù)求和實例講解BinaryOperator的用法:

@TestpublicvoidtestBinaryOperator(){inta1=10;inta2=20;intsum=binaryOperate(a1,a2,(Integer i1,Integer i2)->i1+i2);// output: 30System.out.println(sum);}private<T>TbinaryOperate(T t1,T t2,BinaryOperator<T>binaryOperator){returnbinaryOperator.apply(t1,t2);}

(3)函數(shù)描述符

BinaryOperator: (T, T) -> T

接受兩個泛型T對象,返回一個泛型T對象悼嫉。

7. 總結(jié)

java.util.function包中定義了很多函數(shù)式抽象接口艇潭,只要記住它們的函數(shù)描述符就可以很方便的知道他們的使用方法。

Predicate: T -> boolean

Consumer: T -> void

Supplier: void -> T

Function: T -> R

UnaryOperator: T -> T

BinaryOperator: (T, T) -> T

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末戏蔑,一起剝皮案震驚了整個濱河市暴区,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌辛臊,老刑警劉巖仙粱,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異彻舰,居然都是意外死亡伐割,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門刃唤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來隔心,“玉大人,你說我怎么就攤上這事尚胞∮不簦” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵笼裳,是天一觀的道長唯卖。 經(jīng)常有香客問我,道長躬柬,這世上最難降的妖魔是什么拜轨? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮允青,結(jié)果婚禮上橄碾,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好法牲,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布史汗。 她就那樣靜靜地躺著,像睡著了一般拒垃。 火紅的嫁衣襯著肌膚如雪淹办。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天恶复,我揣著相機與錄音怜森,去河邊找鬼。 笑死谤牡,一個胖子當(dāng)著我的面吹牛副硅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播翅萤,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼恐疲,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了套么?” 一聲冷哼從身側(cè)響起培己,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎胚泌,沒想到半個月后省咨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡玷室,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年零蓉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片穷缤。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡敌蜂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出津肛,到底是詐尸還是另有隱情章喉,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布身坐,位于F島的核電站秸脱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏掀亥。R本人自食惡果不足惜撞反,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一妥色、第九天 我趴在偏房一處隱蔽的房頂上張望搪花。 院中可真熱鬧,春花似錦、人聲如沸撮竿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽幢踏。三九已至髓需,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間房蝉,已是汗流浹背僚匆。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留搭幻,地道東北人咧擂。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像檀蹋,于是被迫代替她去往敵國和親松申。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345