Java8 新特性----函數式介面,以及和Lambda表達式的關係

来源:http://www.cnblogs.com/ownraul/archive/2016/06/01/5551545.html
-Advertisement-
Play Games

這裡來講解一下Java8 新特性中的函數式介面, 以及和Lambda 表達式的關係。看到過很多不少介紹Java8特性的文章,都會介紹到函數式介面和lambda表達式,但是都是分別介紹,沒有將兩者的關係說明清楚,在這裡,把自己的理解整理如下: 一、函數式介面: 函數式介面其實本質上還是一個介面,但是它 ...


   這裡來講解一下Java8 新特性中的函數式介面, 以及和Lambda 表達式的關係。看到過很多不少介紹Java8特性的文章,都會介紹到函數式介面和lambda表達式,但是都是分別介紹,沒有將兩者的關係說明清楚,在這裡,把自己的理解整理如下:

 

一、函數式介面:

  函數式介面其實本質上還是一個介面,但是它是一種特殊的介面:SAM類型的介面(Single Abstract Method)。定義了這種類型的介面,使得以其為參數的方法,可以在調用時,使用一個lambda表達式作為參數。從另一個方面說,一旦我們調用某方法,可以傳入lambda表達式作為參數,則這個方法的參數類型,必定是一個函數式的介面,這個類型必定會使用@FunctionalInterface進行修飾。

  從SAM原則上講,這個介面中,只能有一個函數需要被實現,但是也可以有如下例外:

    1. 預設方法與靜態方法並不影響函數式介面的契約,可以任意使用,即

      函數式介面中可以有靜態方法,一個或者多個靜態方法不會影響SAM介面成為函數式介面,並且靜態方法可以提供方法實現

      可以由 default 修飾的預設方法方法,這個關鍵字是Java8中新增的,為的目的就是使得某一些介面,原則上只有一個方法被實現,但是由於歷史原因,不得不加入一些方法來相容整個JDK中的API,所以就需要使用default關鍵字來定義這樣的方法

    2. 可以有 Object 中覆蓋的方法,也就是 equals,toString,hashcode等方法。

  JDK中以前所有的函數式介面都已經使用 @FunctionalInterface 定義,可以通過查看JDK源碼來確認,以下附JDK 8之前已有的函數式介面:

            java.lang.Runnable

            java.util.concurrent.Callable

            java.security.PrivilegedAction

            java.util.Comparator

            java.io.FileFilter

            java.nio.file.PathMatcher 

            java.lang.reflect.InvocationHandler

            java.beans.PropertyChangeListener

            java.awt.event.ActionListener  

            javax.swing.event.ChangeListener

如:

@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

以下為一個自定義函數式介面的示例:

定義:

@FunctionalInterface
interface Converter<F, T> {

    T convert(F from);

}

使用:

Converter<String, Integer> converter = (from) -> Integer.valueOf(from);

Integer converted = converter.convert("123");

註:方法和構造函數引用在Java8中可以通過 :: 操作符調用

 

  自行設計的方法中, 如果可以接收 lambda 表達式, 則可以使用 Function 作為參數, 如下為一些已經實現的函數式介面:

     // Function<T, R> -T作為輸入,返回的R作為輸出

    Function<String,String> function = (x) -> {System.out.print(x+": ");return "Function";};

    System.out.println(function.apply("hello world"));

  

    //Predicate<T> -T作為輸入,返回的boolean值作為輸出

    Predicate<String> pre = (x) ->{System.out.print(x);return false;};

    System.out.println(": "+pre.test("hello World"));

 

    //Consumer<T> - T作為輸入,執行某種動作但沒有返回值

    Consumer<String> con = (x) -> {System.out.println(x);};

    con.accept("hello world");

 

    //Supplier<T> - 沒有任何輸入,返回T

    Supplier<String> supp = () -> {return "Supplier";};

    System.out.println(supp.get());

 

    //BinaryOperator<T> -兩個T作為輸入,返回一個T作為輸出,對於“reduce”操作很有用

    BinaryOperator<String> bina = (x,y) ->{System.out.print(x+" "+y);return "BinaryOperator";};

    System.out.println("  "+bina.apply("hello ","world"));

 

二、Lambda表達式(這裡只是簡單提一下)

書寫方法:  e -> System.out.println( e )

    1. 三部分構成

        參數列表

        符號 ->

        函數體 : 有多個語句,可以用{} 包括, 如果需要返回值且只有一個語句,可以省略 return

    2. 訪問控制:

        可以訪問類的成員變數和局部變數(非final會自動隱含轉為final)

 

  以上主要是對於函數式介面的一些簡單介紹,如有疏漏,歡迎指正


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 引言 對於 Python 來說,並不缺少併發選項,其標準庫中包括了對線程、進程和非同步 I/O 的支持。在許多情況下,通過創建諸如非同步、線程和子進程之類的高層模塊,Python 簡化了各種併發方法的使用。除了標準庫之外,還有一些第三方的解決方案,例如 Twisted、Stackless 和進程模塊。本 ...
  • Apache和IIS分別有自己的偽靜態操作方法,那在Servers2003_IIS需要給PHP程式使用偽靜態呢?安裝rewrite插件包。 一、下載rewrite插件包,一般裡面必須有httpd.ini和Rewrite.dll,如圖: 二、一般推薦將偽靜態包放至網站根目錄下,然後在需要偽靜態的網站右 ...
  • 編譯器到底做了什麼實現的虛函數的晚綁定呢?我們來探個究竟。 編譯器對每個包含虛函數的類創建一個表(稱為V TA B L E)。在V TA B L E中,編譯器放置特定類的虛函數地址。在每個帶有虛函數的類 中,編譯器秘密地置一指針,稱為v p o i n t e r(縮寫為V P T R),指向這個對 ...
  • 適用場合: 7.3 工廠模式的適用場合 創建新對象最簡單的辦法是使用new關鍵字和具體類。只有在某些場合下,創建和維護對象工廠所帶來的額外複雜性才是物有所值。本節概括了這些場合。 7.3.1 動態實現 如果需要像前面自行車的例子一樣,創建一些用不同方式實現同一介面的對象,那麼可以使用一個工廠方法或簡 ...
  • http://blog.csdn.net/hil2000/article/details/41261267/ 一.我為什麼要學習go語言 當今已經是移動和雲計算時代,Go出現在了工業向雲計算轉型的時刻,簡單、高效、內 置併發原語和現代的標準庫讓Go語言尤其適合雲端軟體開發(畢竟它就是為此而設計的)。 ...
  • 上一篇 從引用傳遞到設計模式 (上) 的文末,提到非虛擬介面 NVI 的實現,即將虛函數聲明為保護型或私有型,藉由模板函數模式來實現 。 園友 @KillU 看的很仔細,提出了一個問題:虛函數是 private 類型,繼承可以麽? 答案是:可以 5 實現權和調用權 <Effective C++> 中 ...
  • 需求描述: 解決過程: 百度一番無果,google一番有了答案。 解決方案: android6.0(api=23)以後直接打開文件,讓系統去判斷如何處理。詳細解決方案見如下地址: http://www.jianshu.com/p/d896a09b9aca 原因分析: http://stackover ...
  • Installation Requirements: Eclipse 4.5 (Mars) or later. Java VM version 8 or later. Gocode and Go oracle. Instructions: For an Eclipse package without ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...