Java 8中的功能接口是什么? @功能注释和示例
函數接口是Java 8最重要的概念之一,實際上為lambda表達式提供了動力,但是許多開發人員沒有首先了解函數接口在Java 8中的作用就花了很多精力來理解它,并花時間學習lambda表達式和Stream API。除非您知道什么是功能接口以及lambda與它之間的關系,否則您將無法使用Java 8的強大功能,例如lambda表達式和流API 。 沒有功能接口的知識,您將無法理解在代碼中可以使用lambda的位置,但是您將很難編寫該方法所期望的lambda表達式,因此,對功能接口有一個很好的了解非常重要。 Java 8。
在本文中,我將通過解釋什么是函數接口,什么是@Functional注釋,它們與lambda表達式之間的關系以及它們如何幫助您在代碼中使用lambda表達式來填補這一空白。 那么,讓我們從第一件事開始,什么是功能接口?
Java 8中的功能接口是什么
好的,功能接口不過是帶有一個抽象方法的接口,例如Comparable , Runnable , EventListener , Comparator等。您可以看到這些接口甚至在JDK 8之前就已經存在于Java中,但是為什么我們將這種接口稱為功能接口呢?
這是一個很好的問題,如果您對函數式編程有所了解,就知道它可以傳遞代碼,即函數,就像將數據或對象傳遞給方法一樣。
這些接口只有一種抽象方法被用于傳遞代碼,就像您以函數式編程語言傳遞函數一樣, 這就是為什么它們被稱為函數接口 。
例如,您可以通過實現Comparator接口來創建一個Anonymous類,從而直接傳遞代碼以比較對象,如下所示:
Collections.sort(list, new Comparator(){public int compare(String s1, String s2){return s1.length() - s2.length();}});因此,如果仔細觀察,您會發現我們正在使用這些接口將代碼傳遞給函數 。 它們也稱為策略接口,因為這是策略模式的實現,其中,構成策略的代碼被注入到在運行時運行該策略的代碼中。
順便說一句,如果您不知道什么是策略模式,那么我建議您從0轉到1:設計模式–至關重要的24 –在Java中 ,因為設計模式的知識對于Java的有效編碼很重要。
那么,既然我們知道什么是功能接口,讓我們了解它們與lambda表達式之間的關系 ,以及對功能接口的理解對于使用lambda表達式編寫代碼有何重要性?
好吧,要記住的最重要的事情是,Java中lambda表達式的唯一用途是將它們轉換為功能接口。
這意味著如果方法接受函數接口 , 則可以傳遞lambda表達式 ,這進一步意味著,可以將lambda傳遞給所有接受方法的現有方法
Comparator , Runnable或任何其他只有一種抽象方法的接口。
這就是Java中lambda表達式也被稱為SAM類型的原因,其中SAM表示單一抽象方法。
@Functional注釋有什么作用?
現在,讓我們看看@Functional注釋是做什么的? 如果僅在其上面添加@Functional注釋,它將使接口起作用嗎? 好吧,不,它不會那樣做。 實際上,
可選的 。
這意味著您可以在不使用@Functioanl批注的情況下創建功能接口,就像可以在不將@Override批注放在方法頂部的情況下@Override方法一樣。 那么, @Functional注釋的真正目的是什么?
好吧,它可以確保該接口實際上只有一種抽象方法,并且還向Javadoc之類的工具提供了此接口是功能性接口的提示。 它與@Override注釋非常相似,后者通過驗證您實際上是重寫方法來幫助防止人為錯誤。
與@Override相似,它的最佳做法是使用單個抽象方法將@Functional批注放在方法的頂部,以向Javadoc等工具表明它們是功能接口。
用@Functional注釋對java.util.function包中添加的所有新功能接口進行注釋。
順便說一句,是的,我們在JDK 8中提供了更多的功能接口,特別是通用功能接口,例如Predicate , Supplier , Consumer , Function , BiFunction , UnaryOperator等。請參見
Java 8:初學者的基礎知識,可深入了解所有這些接口。
這些功能接口允許您以lambda表達式的形式將代碼傳遞給函數,并允許創建可以對這些代碼進行操作的強大方法,例如
filter()接受謂詞,并允許您傳遞接受一個參數并返回布爾值的代碼。
功能接口和Lamda表達式如何關聯
功能接口的知識如何影響lambda表達式的編寫? 好吧,除非您不了解功能接口,否則您將無法編寫可轉換為該功能接口的lambda表達式。
例如, java.util.Map接口的merge()方法接受BiFunction,但是如果您不知道什么是BiFunction,則無法為此編寫lambda。
BiFunction是一個功能接口,具有一個接受兩個參數T和U并返回對象R的方法。
這意味著您可以將lambda傳遞給此方法,該方法可處理兩個參數并返回一個對象,例如merge(key, value, (v1, v2) -> v1 + v2)這里(v1, V2) -> v1 + v2是一個可以轉換為BiFunction功能接口實例的lambda表達式。
一個更簡單的示例是Predicate ,它接受類型T并返回一個布爾值。 如果您看Stream類的filter()方法,它將接受一個謂詞:
filter(Predicate predicate)這意味著您可以傳遞任何接受一個參數的lambda表達式,然后將布爾值返回給該方法,例如age -> age > 15 or s -> s.length == 15 ,這兩個都是可接受的,但是如果您不知道什么是a謂詞接口,那么您將無法做到這一點。
功能接口的另一個示例是Consumer ,它接受類型T的參數并且不返回任何內容。 JDK 8中Iterable的forEach()方法很好地利用了這一點,如下所示:
forEach(Consumer action)您會看到forEach()接受了Consumer,這意味著您可以向其傳遞一個lambda表達式,該表達式具有一個參數,不返回任何內容或返回空值,例如
s -> System.out.println(s)代碼System.out.println()返回任何內容,它僅在控制臺中打印行。
您可以看到,如果您知道功能接口,則可以輕松編寫lambda表達式以進行傳遞,因此必須對功能接口有充分的了解。 我建議您遍歷java.util.function包中的所有功能接口并了解它們。
我將在以后的文章java.util.function包中的一些更復雜的功能接口,但是如果您迫不及待,那么我建議您學習此Java 9 Master Class課程,以了解有關Lambda和其他Java的更多信息。 8個概念。
這就是Java中的功能接口 。 您還了解了@Functional批注的作用以及為什么要對Java 8中的代碼中的lambda表達式進行有效使用需要對功能接口有充分的了解。如果您尚未開始使用Java 8,建議您這樣做。之所以這樣做,是因為在未來幾年中,每個人都將使用Java 8進行編碼,如果您不知道lambda表達式和Java 8中引入的新功能,那么您將被拋在后面。
其他Java 8教程和參考資料,供進一步學習
Java 8的新增功能:Lambdas
如何使用Lambda按鍵和值對HashMay進行排序?
如何在Java 8中使用map和flatMap?
如何在Java 8中進行Map Reduce?
如何在Java 8中將lambda表達式轉換為方法引用?
Java SE 8新功能–完整指南
感謝您到目前為止閱讀本文。 如果您喜歡我對Functional接口和@Functional注釋的解釋,請與您的朋友和同事分享。 如果您有任何疑問或反饋,請發表評論。
翻譯自: https://www.javacodegeeks.com/2018/01/functional-interface-java-8-functional-annotation-examples.html
總結
以上是生活随笔為你收集整理的Java 8中的功能接口是什么? @功能注释和示例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 品牌三十周年 DTS携旗下家庭娱乐、移动
- 下一篇: 向Java最佳专家的全球专家学习Java