摘要:接口有一個(gè)方法,可以返回值。在上面的代碼中,就是獲取字符串的長(zhǎng)度,然后將每個(gè)字符串的長(zhǎng)度作為返回值返回。
今天我們還講講Consumer、Supplier、Predicate、Function這幾個(gè)接口的用法,在 Java8 的用法當(dāng)中,這幾個(gè)接口雖然沒(méi)有明目張膽的使用,但是,卻是潤(rùn)物細(xì)無(wú)聲的。為什么這么說(shuō)呢?
這幾個(gè)接口都在 java.util.function 包下的,分別是Consumer(消費(fèi)型)、supplier(供給型)、predicate(謂詞型)、function(功能性),相信有了后面的解釋?zhuān)銘?yīng)該非常清楚這個(gè)接口的功能了。
那么,下面,我們從具體的應(yīng)用場(chǎng)景來(lái)講講這個(gè)接口的用法!
1 Consumer接口從字面意思上我們就可以看得出啦,consumer接口就是一個(gè)消費(fèi)型的接口,通過(guò)傳入?yún)?shù),然后輸出值,就是這么簡(jiǎn)單,Java8 的一些方法看起來(lái)很抽象,其實(shí),只要你理解了就覺(jué)得很好用,并且非常的簡(jiǎn)單。
我們下面就先看一個(gè)例子,然后再來(lái)分析這個(gè)接口。
1.1 Consumer實(shí)例/** * consumer接口測(cè)試 */ @Test public void test_Consumer() { //① 使用consumer接口實(shí)現(xiàn)方法 Consumerconsumer = new Consumer () { @Override public void accept(String s) { System.out.println(s); } }; Stream stream = Stream.of("aaa", "bbb", "ffffd", "ccc", "fff"); stream.forEach(consumer); System.out.println("********************"); //② 使用lambda表達(dá)式,forEach方法需要的就是一個(gè)Consumer接口 stream = Stream.of("aaa", "bbb", "ffffd", "ccc", "fff"); Consumer consumer1 = (s) -> System.out.println(s);//lambda表達(dá)式返回的就是一個(gè)Consumer接口 stream.forEach(consumer1); //更直接的方式 //stream.forEach((s) -> System.out.println(s)); System.out.println("********************"); //③ 使用方法引用,方法引用也是一個(gè)consumer stream = Stream.of("aaa", "bbb", "ffffd", "ccc", "fff"); Consumer consumer2 = System.out::println; stream.forEach(consumer); //更直接的方式 //stream.forEach(System.out::println); }
輸出結(jié)果
① consumer接口分析
在代碼①中,我們直接創(chuàng)建 Consumer 接口,并且實(shí)現(xiàn)了一個(gè)名為 accept 的方法,這個(gè)方法就是這個(gè)接口的關(guān)鍵了。
我們看一下 accept 方法;這個(gè)方法傳入一個(gè)參數(shù),不返回值。當(dāng)我們發(fā)現(xiàn) forEach 需要一個(gè) Consumer 類(lèi)型的參數(shù)的時(shí)候,傳入之后,就可以輸出對(duì)應(yīng)的值了。
② lambda 表達(dá)式作為 consumer
Consumerconsumer1 = (s) -> System.out.println(s);//lambda表達(dá)式返回的就是一個(gè)Consumer接口
在上面的代碼中,我們使用下面的 lambda 表達(dá)式作為 Consumer 。仔細(xì)的看一下你會(huì)發(fā)現(xiàn),lambda 表達(dá)式返回值就是一個(gè) Consumer ;所以,你也就能夠理解為什么 forEach 方法可以使用 lamdda 表達(dá)式作為參數(shù)了吧。
③ 方法引用作為 consumer
Consumer consumer2 = System.out::println;
在上面的代碼中,我們用了一個(gè)方法引用的方式作為一個(gè) Consumer ,同時(shí)也可以傳給 forEach 方法。
1.3 其他 Consumer 接口除了上面使用的 Consumer 接口,還可以使用下面這些 Consumer 接口。
IntConsumer、DoubleConsumer、LongConsumer、BiConsumer,使用方法和上面一樣。
看完上面的實(shí)例我們可以總結(jié)為幾點(diǎn)。
① Consumer是一個(gè)接口,并且只要實(shí)現(xiàn)一個(gè) accept 方法,就可以作為一個(gè)“消費(fèi)者”輸出信息。
② 其實(shí),lambda 表達(dá)式、方法引用的返回值都是 Consumer 類(lèi)型,所以,他們能夠作為 forEach 方法的參數(shù),并且輸出一個(gè)值。
Supplier 接口是一個(gè)供給型的接口,其實(shí),說(shuō)白了就是一個(gè)容器,可以用來(lái)存儲(chǔ)數(shù)據(jù),然后可以供其他方法使用的這么一個(gè)接口,是不是很明白了,如果還是不明白,看看下面的例子,一定徹底搞懂!
2.1 Supplier實(shí)例** * Supplier接口測(cè)試,supplier相當(dāng)一個(gè)容器或者變量,可以存儲(chǔ)值 */ @Test public void test_Supplier() { //① 使用Supplier接口實(shí)現(xiàn)方法,只有一個(gè)get方法,無(wú)參數(shù),返回一個(gè)值 Suppliersupplier = new Supplier () { @Override public Integer get() { //返回一個(gè)隨機(jī)值 return new Random().nextInt(); } }; System.out.println(supplier.get()); System.out.println("********************"); //② 使用lambda表達(dá)式, supplier = () -> new Random().nextInt(); System.out.println(supplier.get()); System.out.println("********************"); //③ 使用方法引用 Supplier supplier2 = Math::random; System.out.println(supplier2.get()); }
輸出結(jié)果
① Supplier接口分析
Suppliersupplier = new Supplier () { @Override public Integer get() { //返回一個(gè)隨機(jī)值 return new Random().nextInt(); } };
看一下這段代碼,我們通過(guò)創(chuàng)建一個(gè) Supplier 對(duì)象,實(shí)現(xiàn)了一個(gè) get 方法,這個(gè)方法無(wú)參數(shù),返回一個(gè)值;所以,每次使用這個(gè)接口的時(shí)候都會(huì)返回一個(gè)值,并且保存在這個(gè)接口中,所以說(shuō)是一個(gè)容器。
② lambda表達(dá)式作為 Supplier
//② 使用lambda表達(dá)式, supplier = () -> new Random().nextInt(); System.out.println(supplier.get()); System.out.println("********************");
上面的這段代碼,我們使用 lambda 表達(dá)式返回一個(gè) Supplier類(lèi)型的接口,然后,我們調(diào)用 get 方法就可以獲取這個(gè)值了。
③ 方法引用作為 Supplier
//③ 使用方法引用 Suppliersupplier2 = Math::random; System.out.println(supplier2.get());
方法引用也是返回一個(gè)Supplier類(lèi)型的接口。
2.3 Supplier 實(shí)例2我們看完第一個(gè)實(shí)例之后,我們應(yīng)該有一個(gè)了解了,下面再看一個(gè)。
/** * Supplier接口測(cè)試2,使用需要Supplier的接口方法 */ @Test public void test_Supplier2() { Streamstream = Stream.of(1, 2, 3, 4, 5); //返回一個(gè)optional對(duì)象 Optional first = stream.filter(i -> i > 4) .findFirst(); //optional對(duì)象有需要Supplier接口的方法 //orElse,如果first中存在數(shù),就返回這個(gè)數(shù),如果不存在,就放回傳入的數(shù) System.out.println(first.orElse(1)); System.out.println(first.orElse(7)); System.out.println("********************"); Supplier supplier = new Supplier () { @Override public Integer get() { //返回一個(gè)隨機(jī)值 return new Random().nextInt(); } }; //orElseGet,如果first中存在數(shù),就返回這個(gè)數(shù),如果不存在,就返回supplier返回的值 System.out.println(first.orElseGet(supplier)); }
輸出結(jié)果
代碼分析
Optionalfirst = stream.filter(i -> i > 4) .findFirst();
使用這個(gè)方法獲取到一個(gè) Optional 對(duì)象,然后,在 Optional 對(duì)象中有 orElse 方法 和 orElseGet 是需要一個(gè) Supplier 接口的。
//optional對(duì)象有需要Supplier接口的方法 //orElse,如果first中存在數(shù),就返回這個(gè)數(shù),如果不存在,就放回傳入的數(shù) System.out.println(first.orElse(1)); System.out.println(first.orElse(7)); System.out.println("********************"); Suppliersupplier = new Supplier () { @Override public Integer get() { //返回一個(gè)隨機(jī)值 return new Random().nextInt(); } }; //orElseGet,如果first中存在數(shù),就返回這個(gè)數(shù),如果不存在,就返回supplier返回的值 System.out.println(first.orElseGet(supplier));
orElse:如果first中存在數(shù),就返回這個(gè)數(shù),如果不存在,就放回傳入的數(shù)
orElseGet:如果first中存在數(shù),就返回這個(gè)數(shù),如果不存在,就返回supplier返回的值
2.4 其他 Supplier 接口除了上面使用的 Supplier 接口,還可以使用下面這些 Supplier 接口。
IntSupplier 、DoubleSupplier 、LongSupplier 、BooleanSupplier ,使用方法和上面一樣。
① Supplier 接口可以理解為一個(gè)容器,用于裝數(shù)據(jù)的。
② Supplier 接口有一個(gè) get 方法,可以返回值。
Predicate 接口是一個(gè)謂詞型接口,其實(shí),這個(gè)就是一個(gè)類(lèi)似于 bool 類(lèi)型的判斷的接口,后面看看就明白了。
3.1 Predicate 實(shí)例/** * Predicate謂詞測(cè)試,謂詞其實(shí)就是一個(gè)判斷的作用類(lèi)似bool的作用 */ @Test public void test_Predicate() { //① 使用Predicate接口實(shí)現(xiàn)方法,只有一個(gè)test方法,傳入一個(gè)參數(shù),返回一個(gè)bool值 Predicatepredicate = new Predicate () { @Override public boolean test(Integer integer) { if(integer > 5){ return true; } return false; } }; System.out.println(predicate.test(6)); System.out.println("********************"); //② 使用lambda表達(dá)式, predicate = (t) -> t > 5; System.out.println(predicate.test(1)); System.out.println("********************"); }
輸出結(jié)果
① Predicate 接口分析
//① 使用Predicate接口實(shí)現(xiàn)方法,只有一個(gè)test方法,傳入一個(gè)參數(shù),返回一個(gè)bool值 Predicatepredicate = new Predicate () { @Override public boolean test(Integer integer) { if(integer > 5){ return true; } return false; } };
這段代碼中,創(chuàng)建了一個(gè) Predicate 接口對(duì)象,其中,實(shí)現(xiàn)類(lèi) test 方法,需要傳入一個(gè)參數(shù),并且返回一個(gè) bool 值,所以這個(gè)接口作用就是判斷!
System.out.println(predicate.test(6));
再看,調(diào)用 test 方法,傳入一個(gè)值,就會(huì)返回一個(gè) bool 值。
② 使用lambda表達(dá)式作為 predicate
//② 使用lambda表達(dá)式, predicate = (t) -> t > 5; System.out.println(predicate.test(1)); System.out.println("********************");
lambda 表達(dá)式返回一個(gè) Predicate 接口,然后調(diào)用 test 方法!
3.3 Predicate 接口實(shí)例2/** * Predicate謂詞測(cè)試,Predicate作為接口使用 */ @Test public void test_Predicate2() { //① 將Predicate作為filter接口,Predicate起到一個(gè)判斷的作用 Predicatepredicate = new Predicate () { @Override public boolean test(Integer integer) { if(integer > 5){ return true; } return false; } }; Stream stream = Stream.of(1, 23, 3, 4, 5, 56, 6, 6); List list = stream.filter(predicate).collect(Collectors.toList()); list.forEach(System.out::println); System.out.println("********************"); }
輸出結(jié)果
這段代碼,首先創(chuàng)建一個(gè) Predicate 對(duì)象,然后實(shí)現(xiàn) test 方法,在 test 方法中做一個(gè)判斷:如果傳入的參數(shù)大于 5 ,就返回 true,否則返回 false;
Streamstream = Stream.of(1, 23, 3, 4, 5, 56, 6, 6); List list = stream.filter(predicate).collect(Collectors.toList()); list.forEach(System.out::println);
這段代碼調(diào)用 Stream 的 filter 方法,filter 方法需要的參數(shù)就是 Predicate 接口,所以在這里只要大于 5 的數(shù)據(jù)就會(huì)輸出。
3.4 Predicate 接口總結(jié)① Predicate 是一個(gè)謂詞型接口,其實(shí)只是起到一個(gè)判斷作用。
② Predicate 通過(guò)實(shí)現(xiàn)一個(gè) test 方法做判斷。
Function 接口是一個(gè)功能型接口,它的一個(gè)作用就是轉(zhuǎn)換作用,將輸入數(shù)據(jù)轉(zhuǎn)換成另一種形式的輸出數(shù)據(jù)。
4.1 Function 接口實(shí)例/** * Function測(cè)試,function的作用是轉(zhuǎn)換,將一個(gè)值轉(zhuǎn)為另外一個(gè)值 */ @Test public void test_Function() { //① 使用map方法,泛型的第一個(gè)參數(shù)是轉(zhuǎn)換前的類(lèi)型,第二個(gè)是轉(zhuǎn)化后的類(lèi)型 Functionfunction = new Function () { @Override public Integer apply(String s) { return s.length();//獲取每個(gè)字符串的長(zhǎng)度,并且返回 } }; Stream stream = Stream.of("aaa", "bbbbb", "ccccccv"); Stream stream1 = stream.map(function); stream1.forEach(System.out::println); System.out.println("********************"); }
輸出結(jié)果
4.2 代碼分析① Function 接口分析
//① 使用map方法,泛型的第一個(gè)參數(shù)是轉(zhuǎn)換前的類(lèi)型,第二個(gè)是轉(zhuǎn)化后的類(lèi)型 Functionfunction = new Function () { @Override public Integer apply(String s) { return s.length();//獲取每個(gè)字符串的長(zhǎng)度,并且返回 } };
這段代碼創(chuàng)建了一個(gè) Function 接口對(duì)象,實(shí)現(xiàn)了一個(gè) apply 方法,這個(gè)方法有一個(gè)輸入?yún)?shù)和一個(gè)輸出參數(shù)。其中,泛型的第一個(gè)參數(shù)是轉(zhuǎn)換前的類(lèi)型,第二個(gè)是轉(zhuǎn)化后的類(lèi)型。
在上面的代碼中,就是獲取字符串的長(zhǎng)度,然后將每個(gè)字符串的長(zhǎng)度作為返回值返回。
② 重要應(yīng)用 map 方法
Streamstream = Stream.of("aaa", "bbbbb", "ccccccv"); Stream stream1 = stream.map(function); stream1.forEach(System.out::println);
在 Function 接口的重要應(yīng)用不得不說(shuō) Stream 類(lèi)的 map 方法了,map 方法傳入一個(gè) Function 接口,返回一個(gè)轉(zhuǎn)換后的 Stream類(lèi)。
4.3 其他 Function 接口除了上面使用的 Function 接口,還可以使用下面這些 Function 接口。
IntFunction 、DoubleFunction 、LongFunction 、ToIntFunction 、ToDoubleFunction 、DoubleToIntFunction 等等,使用方法和上面一樣。
① Function 接口是一個(gè)功能型接口,是一個(gè)轉(zhuǎn)換數(shù)據(jù)的作用。
② Function 接口實(shí)現(xiàn) apply 方法來(lái)做轉(zhuǎn)換。
通過(guò)前面的介紹,已經(jīng)對(duì)Consumer、Supplier、Predicate、Function這幾個(gè)接口有詳細(xì)的了解了,其實(shí),這幾個(gè)接口并不是很難,只是有點(diǎn)抽象,多加理解會(huì)發(fā)現(xiàn)很簡(jiǎn)單,并且特別好用!
文章有不當(dāng)之處,歡迎指正,如果喜歡微信閱讀,你也可以關(guān)注我的微信公眾號(hào):好好學(xué)java,獲取優(yōu)質(zhì)學(xué)習(xí)資源。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/75761.html
摘要:上一篇小樂(lè)帶大家學(xué)過(guò)新特性表達(dá)式,什么時(shí)候可以使用通常表達(dá)式是用在函數(shù)式接口上使用的。使用實(shí)現(xiàn)創(chuàng)建產(chǎn)生一個(gè)工廠對(duì)象以上就是小樂(lè)帶給大家的新特性之函數(shù)式接口,下一篇將會(huì)為大家?guī)?lái)新特性之方法引用,敬請(qǐng)關(guān)注。 上一篇小樂(lè)帶大家學(xué)過(guò) Java8新特性-Lambda表達(dá)式,什么時(shí)候可以使用Lambda?通常Lambda表達(dá)式是用在函數(shù)式接口上使用的。從Java8開(kāi)始引入了函數(shù)式接口,其說(shuō)明比較...
摘要:大家好,上一篇小樂(lè)給大家講述了樂(lè)字節(jié)核心特性表達(dá)式,點(diǎn)擊回顧。接下來(lái)繼續(xù)核心特性之函數(shù)式接口。感謝大家欣賞小樂(lè)帶來(lái)的核心特性之函數(shù)式接口,接下來(lái)還會(huì)更多核心技術(shù)講解,請(qǐng)關(guān)注樂(lè)字節(jié)如需要視頻課程,請(qǐng)搜索樂(lè)字節(jié)騰訊課堂 大家好,上一篇小樂(lè)給大家講述了《樂(lè)字節(jié)-Java8核心特性-Lambda表達(dá)式》,點(diǎn)擊回顧。接下來(lái)繼續(xù):Java8核心特性之函數(shù)式接口。 什么時(shí)候可以使用Lambda?通常...
摘要:接下來(lái)看下如果使用提供的接口會(huì)有哪些改進(jìn)首先看下接口定義省略該函數(shù)式接口唯一的抽象方法接收一個(gè)參數(shù),有返回值。是不是有點(diǎn)體驗(yàn)到函數(shù)式編程的靈活之處。 上一篇文章中,我們總體介紹了創(chuàng)建函數(shù)式接口實(shí)例的幾種方式以及Java8中接口新增的默認(rèn)方法特性,接下來(lái)我們來(lái)看下Java8中已經(jīng)為我們提供的幾種典型的函數(shù)式接口先看一個(gè)示例 public class FunctionTest { ...
摘要:和不同,其沒(méi)有接收參數(shù)。用于剔除重復(fù),與數(shù)據(jù)庫(kù)中的用法一致??梢詫?duì)整型流求最大值,返回。這兩個(gè)方法是結(jié)束操作,只能調(diào)用一次。 常用的函數(shù)接口記錄方便以后翻吧 接口 參數(shù) 返回類(lèi)型 說(shuō)明 Predicate T boolean 輸入某個(gè)值,輸出boolean 值,用于對(duì)某值進(jìn)行判定 Consumer T void 輸入某值,無(wú)輸出。用于消費(fèi)某值 Function T R...
摘要:上下文比如接受它傳遞的方法的參數(shù),或接受它的值的局部變量中表達(dá)式需要的類(lèi)型稱(chēng)為目標(biāo)類(lèi)型。但局部變量必須顯式聲明為,或事實(shí)上是。換句話說(shuō),表達(dá)式只能捕獲指派給它們的局部變量一次。注捕獲實(shí)例變量可以被看作捕獲最終局部變量。 簡(jiǎn)介 概念 Lambda 表達(dá)式可以理解為簡(jiǎn)潔地表示可傳遞的匿名函數(shù)的一種方式:它沒(méi)有名稱(chēng),但它有參數(shù)列表、函數(shù)主體、返回類(lèi)型,可能還有一個(gè)可以拋出的異常列表。 匿名...
閱讀 954·2021-11-25 09:43
閱讀 2291·2019-08-30 15:55
閱讀 3153·2019-08-30 15:44
閱讀 2053·2019-08-29 16:20
閱讀 1453·2019-08-29 12:12
閱讀 1609·2019-08-26 12:19
閱讀 2283·2019-08-26 11:49
閱讀 1712·2019-08-26 11:42