<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
前言:
在Java8支援Lambda表示式以後,為了滿足Lambda
表示式的一些典型使用場景,JDK為我們提供了大量常用的函數式介面。它們主要在 java.util.function
包中,下面簡單介紹幾個其中的介面及其使用範例。
Supplier
介面是物件範例的提供者,定義了一個名叫get
的抽象方法,它沒有任何入參,並返回一個泛型T物件,具體原始碼如下:
package java.util.function; @FunctionalInterface public interface Supplier<T> { T get(); }
原始碼比較簡單,我們來個例子。這是之前提過的表示口罩的類:
package one.more.study; /** * 口罩 */ public class Mask { public Mask(String brand, String type) { this.brand = brand; this.type = type; } /** * 品牌 */ private String brand; /** * 型別 */ 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
表示式宣告一個Supplier
的範例:
Supplier<Mask> supplier = () -> new Mask("3M", "N95");
用它來建立品牌為3M、型別為N95的Mask
範例:
Mask mask = supplier.get(); System.out.println("Brand: " + mask.getBrand() + ", Type: " + mask.getType());
執行結果如下:
Brand: 3M, Type: N95
特別需要注意的是,本例中每一次呼叫get
方法都會建立新的物件。
Consumer
介面是一個類似消費者的介面,定義了一個名叫accept
的抽象方法,它的入參是一個泛型T物件,沒有任何返回(void),主要原始碼如下:
package java.util.function; @FunctionalInterface public interface Consumer<T> { void accept(T t); }
結合上面的Supplier
介面,我們來個例子:
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表示式宣告一個Supplier
的範例,它是用來建立品牌為3M、型別為N95的Mask
範例;再使用Lambda表示式宣告一個Consumer
的範例,它是用於列印出Mask
範例的相關資訊;最後Consumer
消費了Supplier
生產的Mask
。
執行結果如下:
Brand: 3M, Type: N95
Predicate
介面是判斷是與否的介面,定義了一個名叫test
的抽象方法,它的入參是一個泛型T物件,並返回一個boolean型別,主要原始碼如下:
package java.util.function; @FunctionalInterface public interface Predicate<T> { boolean test(T t); }
結合上面的Supplier
介面,我們來個例子:
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表示式宣告一個Supplier
的範例,它是用來建立品牌為3M、型別為N95的Mask
範例;再使用Lambda表示式宣告一個Predicate
的範例n95,它是用於判斷是否為N95口罩;再使用Lambda表示式宣告一個Predicate
的範例kn95,它是用於判斷是否為KN95口罩;最後分別用兩個Predicate
判斷Supplier
生產的Mask
。
執行結果如下:
是否為N95口罩:true
是否為KN95口罩:false
Function
介面是對範例進行處理轉換的介面,定義了一個名叫apply
的抽象方法,它的入參是一個泛型T物件,並返回一個泛型R物件,主要原始碼如下:
package java.util.function; @FunctionalInterface public interface Function<T, R> { R apply(T t); }
結合上面的Supplier
介面,我們來個例子:
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("口罩型別:" + type.apply(supplier.get()));
首先使用Lambda表示式宣告一個Supplier
的範例,它是用來建立品牌為3M、型別為N95的Mask
範例;再使用Lambda表示式宣告一個Function
的範例brand,它是用於獲取口罩的品牌;再使用Lambda表示式宣告一個Function
的範例type,它是用於獲取口罩的型別;最後分別用兩個Function
分析Supplier
生產的Mask
。
執行結果如下:
口罩品牌:3M
口罩型別:N95
Function
介面的入參只有一個泛型物件,JDK還為我們提供了兩個泛型物件入參的介面:BiFunction
介面,主要原始碼如下:
package java.util.function; @FunctionalInterface public interface BiFunction<T, U, R> { R apply(T t, U u); }
我們可以用BiFunction
介面傳入兩個String
直接建立Mask
範例:
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());
執行結果如下:
Brand: 3M, Type: N95
以上介紹的幾個常用的函數式介面入參和返回,都是泛型物件的,也就是必須為參照型別。當我們傳入或獲取的是基本資料型別時,將會發生自動裝箱和自動拆箱,帶來不必要的效能損耗,比如:
Supplier<Long> supplier = () -> System.currentTimeMillis(); long timeMillis = supplier.get();
在上面例子裡,發生了一次自動裝箱(long被裝箱為Long)和一次自動拆箱(Long被拆箱為long),如何避免這種不必要的效能損耗呢?JDK為我們提供相應的函數式介面,如LongSupplier
介面,定義了一個名叫getAsLong
的抽象方法,簽名是() -> long
。
上面的例子可以優化為:
LongSupplier supplier = () -> System.currentTimeMillis(); long timeMillis = supplier.getAsLong();
類似這樣的介面還有很多,我為大家整理了一下:
介面名稱 | 方法名稱 | 方法簽名 |
---|---|---|
Supplier | get | () -> T |
BooleanSupplier | getAsBoolean | () -> boolean |
DoubleSupplier | getAsDouble | () -> double |
IntSupplier | getAsInt | () -> int |
LongSupplier | getAsLong | () -> long |
介面名稱 | 方法名稱 | 方法簽名 |
---|---|---|
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 | test | (T) -> boolean |
BiPredicate | test | (T, U) -> boolean |
DoublePredicate | test | (double) -> boolean |
IntPredicate | test | (int) -> boolean |
LongPredicate | test | (long) -> boolean |
介面名稱 | 方法名稱 | 方法簽名 |
---|---|---|
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 |
到此這篇關於Java Lambda表示式常用的函數式介面的文章就介紹到這了,更多相關Lambda函數式介面內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45