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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...