摘要:最后我們來看下創建函數式接口的最后一種,第三種方式構造方法引用,繼續改程序構造方法引用構造方法引用的語法是類名我們給新添加了一個構造方法,該構造方法接收一個參數,不返回值,編譯通過。
上一篇文章中,我們簡單介紹了Java8的Lambda表達式以及函數式接口的概念,接下來我們繼續深入Java8函數式編程模型。
public class Test1 { public static void main(String[] args) { Listlist = Arrays.asList(1,2,3,4,5,6,7,8,9,10); list.forEach(new Consumer () { @Override public void accept(Integer integer) { System.out.println(integer); } }); } }
這段程序很簡單,首先初始化一個Integer類型的集合然后向控制臺輸出每個元素。其中我們注意到forEach方法,它就是Java8中新增加的默認方法。
public interface Iterable{ . .省略 . default void forEach(Consumer super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } }
它被聲明在Iterable接口中,并被關鍵字default修飾。這樣任何一個該接口的子類型都可以繼承forEach方法的實現,所以List接口因為是Iterable的間接子接口,所以也繼承了該默認方法。Java8采用這種巧妙的方式既擴展了接口的功能,又兼容了老版本。
接下來分析下forEach的實現,首先接收了一個Consumer類型的參數action,進行非空判斷,然后遍歷當前所有元素交由action的accept方法進行處理。那么Consumer又是什么鬼,看源碼
@FunctionalInterface public interface Consumer{ /** * Performs this operation on the given argument. * * @param t the input argument */ void accept(T t); . .省略 . }
一個接口,有且僅有一個抽象方法,被@FunctionalInterface修飾,典型的函數式接口。
ok,現在我們知道forEach接收的Consumer類型的參數是一個函數式接口,接口里唯一的accept抽象方法接收一個參數,不返回值。那通過上一篇文章我們知道,創建函數式接口類型的實例其中一種方式是使用Lambda表達式,所以可以將最上面的程序改造一下
public class Test1 { public static void main(String[] args) { Listlist = Arrays.asList(1,2,3,4,5,6,7,8,9,10); //Lambda表達式 接收一個參數 不返回值 list.forEach(item -> System.out.println(item)); } }
該lambda表達式item -> System.out.println(item)接收一個參數 不返回值,符合accept方法定義,編譯通過。
也就是說如果使用lambda表達式來創建一個函數式接口實例,那這個lambda表達式的入參和返回必須符合這個函數式接口中唯一的抽象方法的定義。
接下來再對程序進行改造
public class Test1 { public static void main(String[] args) { Listlist = Arrays.asList(1,2,3,4,5,6,7,8,9,10); //方法引用 list.forEach(System.out::println); } }
看到out后面有兩個冒號,反正當時我是凌亂了。。。這個就是函數式接口實例第二種創建方式:方法引用
方法引用的語法是 對象::方法名(只是其中一種)
同樣,使用方法引用方式去創建函數式接口實例也必須遵守方法的定義,看下此處println方法源碼
public void println(Object x) { String s = String.valueOf(x); synchronized (this) { print(s); newLine(); } }
接收一個參數,并不返回值,編譯通過。
最后我們來看下創建函數式接口的最后一種,第三種方式:構造方法引用 ,繼續改程序
public class Test1 { public static void main(String[] args) { Listlist = Arrays.asList(1,2,3,4,5,6,7,8,9,10); //構造方法引用 list.forEach(Test1::new); } Test1(Integer i){ System.out.println(i); } }
構造方法引用的語法是:類名::new
我們給Test1新添加了一個構造方法,該構造方法接收一個參數,不返回值,編譯通過。(僅為展示構造方法引用的用法)
結合上一篇文章可以總結一下,創建函數式接口類型的三種方式:
1.lambda表達式
2.方法引用
3.構造方法引用
注意:無論是哪種方式,必須要符合抽象方法的方法定義
小結:本篇我們首先介紹了接口中的默認方法,然后又分別用幾段程序代碼展示了方法引用和構造方法引用的使用方式,后續還會提供一些示例來加深理解,如果覺得本篇文章對你有所幫助幫忙贊一下哈。
下一篇
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70678.html
摘要:新特性總覽標簽本文主要介紹的新特性,包括表達式方法引用流默認方法組合式異步編程新的時間,等等各個方面。還有對應的和類型的函數連接字符串廣義的歸約匯總起始值,映射方法,二元結合二元結合。使用并行流時要注意避免共享可變狀態。 Java8新特性總覽 標簽: java [TOC] 本文主要介紹 Java 8 的新特性,包括 Lambda 表達式、方法引用、流(Stream API)、默認方...
摘要:類與對象基本概念如果在之后跟著的是一個包含有類名的字符串,則該類的一個實例被創建。如果該類屬于一個名字空間,則必須使用其完整名稱。如果一個類被聲明為,則不能被繼承。命名空間通過關鍵字來聲明。 類與對象 基本概念 new:如果在 new 之后跟著的是一個包含有類名的字符串,則該類的一個實例被創建。如果該類屬于一個名字空間,則必須使用其完整名稱。 Example #3 創建一個實例 ...
摘要:將構造函數的作用域賦值給新的對象因此指向了這個新對象。以這種方式定義的構造函數是定義在對象在瀏覽器是對象中的。構造函數在不返回值的情況下,默認會返回新對象實例。在創建子類型的實例時,不能向超類型的構造函數中傳遞參數。 創建對象 雖然Object構造函數或對象字面量都可以用來創建單個對象,但是這些方式有明顯的缺點:使用同一個接口創建很多對象,會產生大量的重復代碼。為解決這個問題,人們開始...
摘要:本文挑選了到大廠面試題,大家在閱讀時,建議不要先看我的答案,而是自己先思考一番。構造函數返回值是或,是返回的是種返回的對象。 今年來,各大公司都縮減了HC,甚至是采取了裁員措施,在這樣的大環境之下,想要獲得一份更好的工作,必然需要付出更多的努力。 本文挑選了20到大廠面試題,大家在閱讀時,建議不要先看我的答案,而是自己先思考一番。盡管,本文所有的答案,都是我在翻閱各種資料,思考并驗證之...
閱讀 3344·2021-11-10 11:36
閱讀 3244·2021-10-08 10:21
閱讀 2841·2021-09-29 09:35
閱讀 2416·2021-09-22 16:06
閱讀 3959·2021-09-09 09:33
閱讀 1327·2019-08-30 15:44
閱讀 3171·2019-08-30 10:59
閱讀 2982·2019-08-29 15:32