程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> Java8 新特性----函數式接口,以及和Lambda表達式的關系,java8lambda

Java8 新特性----函數式接口,以及和Lambda表達式的關系,java8lambda

編輯:JAVA綜合教程

Java8 新特性----函數式接口,以及和Lambda表達式的關系,java8lambda


   這裡來講解一下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)

 

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved