Java?Lambda表達(dá)式常用的函數(shù)式接口
前言:
在Java8支持Lambda表達(dá)式以后,為了滿足Lambda表達(dá)式的一些典型使用場(chǎng)景,JDK為我們提供了大量常用的函數(shù)式接口。它們主要在 java.util.function 包中,下面簡(jiǎn)單介紹幾個(gè)其中的接口及其使用示例。
Supplier接口
Supplier接口是對(duì)象實(shí)例的提供者,定義了一個(gè)名叫get的抽象方法,它沒(méi)有任何入?yún)?,并返回一個(gè)泛型T對(duì)象,具體源碼如下:
package java.util.function;
@FunctionalInterface
public interface Supplier<T> {
T get();
}
源碼比較簡(jiǎn)單,我們來(lái)個(gè)例子。這是之前提過(guò)的表示口罩的類(lèi):
package one.more.study;
/**
* 口罩
*/
public class Mask {
public Mask(String brand, String type) {
this.brand = brand;
this.type = type;
}
/**
* 品牌
*/
private String brand;
/**
* 類(lèi)型
*/
private String type;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
下面我們使用Lambda表達(dá)式聲明一個(gè)Supplier的實(shí)例:
Supplier<Mask> supplier = () -> new Mask("3M", "N95");
用它來(lái)創(chuàng)建品牌為3M、類(lèi)型為N95的Mask實(shí)例:
Mask mask = supplier.get();
System.out.println("Brand: " + mask.getBrand() + ", Type: " + mask.getType());
運(yùn)行結(jié)果如下:
Brand: 3M, Type: N95
特別需要注意的是,本例中每一次調(diào)用get方法都會(huì)創(chuàng)建新的對(duì)象。
Consumer接口
Consumer接口是一個(gè)類(lèi)似消費(fèi)者的接口,定義了一個(gè)名叫accept的抽象方法,它的入?yún)⑹且粋€(gè)泛型T對(duì)象,沒(méi)有任何返回(void),主要源碼如下:
package java.util.function;
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
結(jié)合上面的Supplier接口,我們來(lái)個(gè)例子:
Supplier<Mask> supplier = () -> new Mask("3M", "N95");
Consumer<Mask> consumer = (Mask mask) -> {
System.out.println("Brand: " + mask.getBrand() + ", Type: " + mask.getType());
};
consumer.accept(supplier.get());
首先使用Lambda表達(dá)式聲明一個(gè)Supplier的實(shí)例,它是用來(lái)創(chuàng)建品牌為3M、類(lèi)型為N95的Mask實(shí)例;再使用Lambda表達(dá)式聲明一個(gè)Consumer的實(shí)例,它是用于打印出Mask實(shí)例的相關(guān)信息;最后Consumer消費(fèi)了Supplier生產(chǎn)的Mask。
運(yùn)行結(jié)果如下:
Brand: 3M, Type: N95
Predicate接口
Predicate接口是判斷是與否的接口,定義了一個(gè)名叫test的抽象方法,它的入?yún)⑹且粋€(gè)泛型T對(duì)象,并返回一個(gè)boolean類(lèi)型,主要源碼如下:
package java.util.function;
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
結(jié)合上面的Supplier接口,我們來(lái)個(gè)例子:
Supplier<Mask> supplier = () -> new Mask("3M", "N95");
Predicate<Mask> n95 = (Mask mask) -> "N95".equals(mask.getType());
Predicate<Mask> kn95 = (Mask mask) -> "KN95".equals(mask.getType());
System.out.println("是否為N95口罩:" + n95.test(supplier.get()));
System.out.println("是否為KN95口罩:" + kn95.test(supplier.get()));
首先使用Lambda表達(dá)式聲明一個(gè)Supplier的實(shí)例,它是用來(lái)創(chuàng)建品牌為3M、類(lèi)型為N95的Mask實(shí)例;再使用Lambda表達(dá)式聲明一個(gè)Predicate的實(shí)例n95,它是用于判斷是否為N95口罩;再使用Lambda表達(dá)式聲明一個(gè)Predicate的實(shí)例kn95,它是用于判斷是否為KN95口罩;最后分別用兩個(gè)Predicate判斷Supplier生產(chǎn)的Mask。
運(yùn)行結(jié)果如下:
是否為N95口罩:true
是否為KN95口罩:false
Function接口
Function接口是對(duì)實(shí)例進(jìn)行處理轉(zhuǎn)換的接口,定義了一個(gè)名叫apply的抽象方法,它的入?yún)⑹且粋€(gè)泛型T對(duì)象,并返回一個(gè)泛型R對(duì)象,主要源碼如下:
package java.util.function;
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
結(jié)合上面的Supplier接口,我們來(lái)個(gè)例子:
Supplier<Mask> supplier = () -> new Mask("3M", "N95");
Function<Mask, String> brand = (Mask mask) -> mask.getBrand();
Function<Mask, String> type = (Mask mask) -> mask.getType();
System.out.println("口罩品牌:" + brand.apply(supplier.get()));
System.out.println("口罩類(lèi)型:" + type.apply(supplier.get()));
首先使用Lambda表達(dá)式聲明一個(gè)Supplier的實(shí)例,它是用來(lái)創(chuàng)建品牌為3M、類(lèi)型為N95的Mask實(shí)例;再使用Lambda表達(dá)式聲明一個(gè)Function的實(shí)例brand,它是用于獲取口罩的品牌;再使用Lambda表達(dá)式聲明一個(gè)Function的實(shí)例type,它是用于獲取口罩的類(lèi)型;最后分別用兩個(gè)Function分析Supplier生產(chǎn)的Mask。
運(yùn)行結(jié)果如下:
口罩品牌:3M
口罩類(lèi)型:N95
BiFunction接口
Function接口的入?yún)⒅挥幸粋€(gè)泛型對(duì)象,JDK還為我們提供了兩個(gè)泛型對(duì)象入?yún)⒌慕涌冢?code>BiFunction接口,主要源碼如下:
package java.util.function;
@FunctionalInterface
public interface BiFunction<T, U, R> {
R apply(T t, U u);
}
我們可以用BiFunction接口傳入兩個(gè)String直接創(chuàng)建Mask實(shí)例:
BiFunction<String,String,Mask> biFunction = (String brand, String type) -> new Mask(brand, type);
Mask mask = biFunction.apply("3M", "N95");
System.out.println("Brand: " + mask.getBrand() + ", Type: " + mask.getType());
運(yùn)行結(jié)果如下:
Brand: 3M, Type: N95
基本數(shù)據(jù)類(lèi)型
以上介紹的幾個(gè)常用的函數(shù)式接口入?yún)⒑头祷?,都是泛型?duì)象的,也就是必須為引用類(lèi)型。當(dāng)我們傳入或獲取的是基本數(shù)據(jù)類(lèi)型時(shí),將會(huì)發(fā)生自動(dòng)裝箱和自動(dòng)拆箱,帶來(lái)不必要的性能損耗,比如:
Supplier<Long> supplier = () -> System.currentTimeMillis(); long timeMillis = supplier.get();
在上面例子里,發(fā)生了一次自動(dòng)裝箱(long被裝箱為L(zhǎng)ong)和一次自動(dòng)拆箱(Long被拆箱為long),如何避免這種不必要的性能損耗呢?JDK為我們提供相應(yīng)的函數(shù)式接口,如LongSupplier接口,定義了一個(gè)名叫getAsLong的抽象方法,簽名是() -> long。
上面的例子可以?xún)?yōu)化為:
LongSupplier supplier = () -> System.currentTimeMillis(); long timeMillis = supplier.getAsLong();
類(lèi)似這樣的接口還有很多,我為大家整理了一下:
Supplier相關(guān)的接口
| 接口名稱(chēng) | 方法名稱(chēng) | 方法簽名 |
|---|---|---|
| Supplier | get | () -> T |
| BooleanSupplier | getAsBoolean | () -> boolean |
| DoubleSupplier | getAsDouble | () -> double |
| IntSupplier | getAsInt | () -> int |
| LongSupplier | getAsLong | () -> long |
Consumer相關(guān)的接口
| 接口名稱(chēng) | 方法名稱(chēng) | 方法簽名 |
|---|---|---|
| Consumer | accept | (T) -> void |
| DoubleConsumer | accept | (double) -> void |
| IntConsumer | accept | (int) -> void |
| LongConsumer | accept | (long) -> void |
| ObjDoubleConsumer | accept | (T, double) -> void |
| ObjIntConsumer | accept | (T, int) -> void |
| ObjLongConsumer | accept | (T, long) -> void |
Predicate相關(guān)的接口
| 接口名稱(chēng) | 方法名稱(chēng) | 方法簽名 |
|---|---|---|
| Predicate | test | (T) -> boolean |
| BiPredicate | test | (T, U) -> boolean |
| DoublePredicate | test | (double) -> boolean |
| IntPredicate | test | (int) -> boolean |
| LongPredicate | test | (long) -> boolean |
Function相關(guān)的接口
| 接口名稱(chēng) | 方法名稱(chēng) | 方法簽名 |
|---|---|---|
| Function | apply | (T) -> R |
| BiFunction | apply | (T, U) -> R |
| DoubleFunction | apply | (double) -> R |
| DoubleToIntFunction | applyAsInt | (double) -> int |
| DoubleToLongFunction | applyAsLong | (double) -> long |
| IntFunction | apply | (int) -> R |
| IntToDoubleFunction | applyAsDouble | (int) -> double |
| IntToLongFunction | applyAsLong | (int) -> long |
| LongFunction | apply | (long) -> R |
| LongToDoubleFunction | applyAsDouble | (long) -> double |
| LongToIntFunction | applyAsInt | (long) -> int |
| ToDoubleFunction | applyAsDouble | (T) -> double |
| ToDoubleBiFunction | applyAsDouble | (T, U) -> double |
| ToIntFunction | applyAsInt | (T) -> int |
| ToIntBiFunction | applyAsInt | (T, U) -> int |
| ToLongFunction | applyAsLong | (T) -> long |
| ToLongBiFunction | applyAsLong | (T, U) -> long |
到此這篇關(guān)于Java Lambda表達(dá)式常用的函數(shù)式接口的文章就介紹到這了,更多相關(guān)Lambda函數(shù)式接口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Tomcat數(shù)據(jù)源配置方法_JBuilder中
今天幫一同事配置一個(gè)數(shù)據(jù)源,采用tomcat5.5.9,本來(lái)是個(gè)很簡(jiǎn)單的事,以前也配過(guò),但由于很長(zhǎng)時(shí)間沒(méi)用過(guò)容器提供的數(shù)據(jù)源了(IOC用慣了),也只記的個(gè)大概了,所以剛開(kāi)始一配就出錯(cuò)了,google了一下,有很多資料,照著試試卻都不好使(到不是別人說(shuō)的不對(duì),只是大家用的版本不同)。2008-10-10
Spring Security使用權(quán)限注解實(shí)現(xiàn)精確控制
在現(xiàn)代的應(yīng)用系統(tǒng)中,權(quán)限管理是確保系統(tǒng)安全性的重要環(huán)節(jié),Spring Security作為Java世界最為普及的安全框架,提供了強(qiáng)大而靈活的權(quán)限控制功能,這篇文章將深入探討Spring Security使用權(quán)限注解實(shí)現(xiàn)精確控制,需要的朋友可以參考下2024-12-12
Spring?Cloud?OpenFeign模版化客戶端搭建過(guò)程
OpenFeign是一個(gè)顯示聲明式的WebService客戶端。使用OpenFeign能讓編寫(xiě)Web Service客戶端更加簡(jiǎn)單,這篇文章主要介紹了Spring?Cloud?OpenFeign模版化客戶端,需要的朋友可以參考下2022-06-06
JavaWeb三大組件之監(jiān)聽(tīng)器Listener詳解
這篇文章主要介紹了JavaWeb三大組件之監(jiān)聽(tīng)器Listener詳解,在JavaWeb應(yīng)用程序中,Listener監(jiān)聽(tīng)器是一種機(jī)制,用于監(jiān)聽(tīng)和響應(yīng)特定的事件,它可以感知并響應(yīng)與應(yīng)用程序相關(guān)的事件,從而執(zhí)行相應(yīng)的邏輯處理,需要的朋友可以參考下2023-10-10
2022年最新java?8?(?jdk1.8u321)安裝圖文教程
這篇文章主要介紹了2022年最新java?8?(?jdk1.8u321)安裝圖文教程,截止2022年1月,官方出的jdk1.8目前已更新到8u321的版本,本文通過(guò)圖文并茂的形式給大家介紹安裝過(guò)程,需要的朋友可以參考下2022-08-08
Spring將MultipartFile轉(zhuǎn)存到本地磁盤(pán)的三種方式
在Java中處理文件向來(lái)是一種不是很方便的操作,然后隨著Spring框架的崛起,使用Spring框架中的MultipartFile來(lái)處理文件也是件很方便的事了,今天就給大家介紹Spring將MultipartFile轉(zhuǎn)存到本地磁盤(pán)的方式,需要的朋友可以參考下2024-10-10

