溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java8中如何實現函數式接口

發布時間:2021-07-28 14:12:08 來源:億速云 閱讀:160 作者:Leah 欄目:編程語言

這篇文章將為大家詳細講解有關Java8中如何實現函數式接口,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

Lambda表達式小試牛刀

Lambada表達式可以理解為:可傳遞的匿名函數的一種簡潔表達方式。Lambda表達式沒有名稱,同普通方法一樣有參數列表、函數主體、返回類型等;

下面簡單看一個例子,new一個線程打印字符串,采用lambda表達式非常簡潔:

new Thread(() -> System.out.println("hello java8 lambda")).start()

Thread類接受一個Runnable類型實例,查看Jdk源碼發現Runnable接口是一個函數式接口,可以直接用lambda表達式替代。

@FunctionalInterface public interface Runnable {     public abstract void run(); }

Lambda表達式語法非常簡單:

() -> System.out.println("hello java8 lambda")
  • ()括號里面是參數列表,如果只有一個參數還可以寫為:a -> System.out.println(a)

  • -> 箭頭為固定寫法;

  • System.out.println("hello java8 lambda") 為函數主體,如果有多條語句要用花括號包裹起來, 比如下面這樣:

(a, b) -> {int sum = a + b; return sum;}

綜上,Lambda表達式模塊可以固化為:

(parameter) -> {expression} 或者 (parameter) -> {statements; statements; }

數只有一個可以省略括號

如果不用Lambda表達式,使用匿名內部類的方式,寫法就不是那么優雅了。

// before Java8 new Thread(new Runnable() {     @Override     public void run() {         System.out.println("hello java8 without lambda");     } }).start();

Lambda高階用法

(1)函數式接口

函數式接口是只定義了一個抽象方法的接口。注意Java8中允許存在默認方法(default),哪怕有很多默認方法,只要有且僅有一個抽象方法,那么這個接口仍然是函數式接口。

函數式接口通常在類上有一個注解@FunctionalInterface,如:

@FunctionalInterface public interface Runnable {     public abstract void run(); }

(2)函數式接口可以干什么?

通常lambda表達式與函數式接口結合一起用,lambda表達式以內聯的形式為函數式接口的抽象方法提供實現,把整個表達式作為函數式接口的實例。在沒有lambda表達式之前,我們通常會使用匿名內部類的方式實現,詳細對比見第一小節的實例代碼。

(3)函數描述符

函數式接口抽象方法的簽名基本上就是lambda表達式的簽名,我們可以將這種對應關系稱為函數描述符。由一個函數式接口的抽象方法抽象為一個函數描述符,這個過程非常重要,知道了函數描述符去寫lambda表達式也就非常容易了。舉個例子:

Runnable接口有一個抽象方法 void run(), 接受空參數返回void,那么函數描述符可以推導為:

  • () -> void

  • lambda表達式可以寫為

  • () -> System.out.println("hello java8 lambda")

(4)常用函數式接口

java8 中常用函數式接口,針對基本類型java還定義了IntPredicate, LongPredicate等類型,詳細可以參考jdk源碼。

函數式接口函數描述符
PredicateT->boolean
ConsumerT->void
Function<T,R>T->R
Supplier() -> T
UnaryOperatorT -> T
BinaryOperator(T,T)->T
BiPredicate<L,R>(L,R)->boolean
BiConsumer<T,U>(T,U)->void
BiFunction<T,U,R>(T,U)->R

至于 Predicate, Consumer, Function這些函數式接口具體作用,在后面的文章中會詳細介紹,這里只需有個大體印象即可。

(5)將lambda表達式重構為方法引用

方法引用可以看作是lambda表達式的一種快捷寫法,它可以調用特性的方法作為參數傳遞。你也可以將方法引用看作是lambda表達式的語法糖,讓lambda表達式寫起來更加簡介。舉個栗子,按學生年齡排序:

// before students.sort((s1, s2) -> s1.getAge.compareTo(s2.getAge())))); // after 使用方法引用 students.sort(Comparator.comparing(Student::getAge()))));

方法引用主要有三類:

  • 靜態方法的方法引用

valueOf是String類的靜態方法,方法引用寫為 String::valueOf, 對應lambda表達式:a ->  String.valueOf(a)

  • 任意類型實例方法的方法引用

length是String類的實例方法,方法引用寫為 String::length,對應lambda表達式:(str) ->  str.length()

  • 現有對象的實例方法的方法引用

第三種容易與第二種混淆,現有對象指的是在lambda表達式中調用外部對象(不是入參對象)的實例方法,比如:

String str = "hello java8"; () -> str.length();

對應方法引用寫為 str::length, 注意不是 String::length

最后我們將三類方法引用歸納如下:

lambda表達式方法引用 
(args) -> ClassName.staticMethod(args)ClassName::staticMethod靜態方法方法引用
(arg0, params) -> arg0.instanceMethod(params)ClassName::instanceMethod內部實例方法引用
arg0
(params) -> arg0.instanceMethod(params)
arg0.instanceMethod外部實例方法引用

關于Java8中如何實現函數式接口就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女