摘要:歐陽思海繼承接口后,又加了新的抽象方法,這個接口就不再是函數式接口默認方法在接口中添加了一個默認方法。總結在這篇文章中,我們講了表達式方法引用函數式接口接口中的靜態方法接口中的默認方法的使用。
今天我來聊聊 Java8 的一些新的特性,確實 Java8 的新特性的出現,給開發者帶來了非常大的便利,可能剛剛開始的時候會有點不習慣的這種寫法,但是,當你真正的熟悉了之后,你一定會愛上這些新的特性的,這篇文章就來聊聊這些新特性。
lambda 表達式lambda 表達式在項目中也是用到了,這種新的語法的加入,對于使用 Java 多年的我,我覺得是如虎添翼的感覺哈,這種新的語法,大大的改善了以前的 Java 的代碼,變得更加的簡潔,我覺得這也是為什么 Java8 能夠很快的流行起來的原因吧。
這里我們用幾個以前的經典的 Java 的寫法和用 lambda 表達式的方式進行對比。
線程的用法
原始的線程用法
//使用匿名內部類的方式啟動多線程 new Thread(new Runnable() { @Override public void run() { System.out.println("這是使用匿名內部類的方式。。。"); } }).start();
lambda 表達式
//使用lambda表達式方式 new Thread(() -> { System.out.println("這是使用lambda表達式的方式。。。"); }).start();
你會發現,用 lambda 表達式的方式能夠寫更少的代碼,看起來也會更加的舒服和簡潔。
這里沒有使用參數,只是一個簡單的例子。
我們再看一個例子。
遍歷方式
原始方式
//原始方式 Listlist = Arrays.asList(1, 2, 3, 4, 5); for (int i : list) { System.out.println(i); }
lambda 表達式方式
//使用lambda表達式代替foreach循環 Stream.of(1, 2, 3, 4, 5).forEach((x) -> { System.out.println(x); });
在原始的方式中,我們一般使用 foreach 的方式進行遍歷,有了 Java8 的方式之后,我們可以用 forEach 方法,然后,再用 lambda 表達式的方式進行遍歷,也讓原來的方式變得更加的簡潔。
在這個例子中,我們加了一個參數,在()中間我們加了一個 x ,代表的意思其實是:通過 forEach 方法,我們把一個元素已經賦值到 x 中了,拿到這個 x ,我們就可以輸出結果。
總結
lambda 的使用方式其實很簡單,可以總結為下面的方法。
([參數可選,...]) -> { }方法引用
方法引用其實是 lambda 表達式的部分的簡化,也就是為了簡化 lambda 表達式而存在的感覺,下面我們還講講怎么使用方法引用。
/** * @return void * @Author ouyangsihai * @Description 方法引用測試 * @Date 10:23 2019/5/14 * @Param [] **/ @Test public void test_method_reference() { //使用lambda表達式 Stream.of("A", "BB", "CCC", "DDDD", "FFFFF") .map(s -> s.length()) //lambda .forEach((x) -> { System.out.println(x); }); //使用靜態方法引用 Stream.of("A", "BB", "CCC", "DDDD", "FFFFF") .map(String::length) //靜態方法引用 .forEach((x) -> { System.out.println(x); }); //使用實例方法引用 Stream.of( new ClassMate("1", "歐陽思海"), new ClassMate("2", "sihai") ).map(ClassMate::getName)//實例方法引用 .forEach(x -> { System.out.println(x); }); }
在第一個測試中,我們用的是 lambda 表達式來獲取每個字符串的長度。
s -> s.length()
在第二個測試中,我們使用的是靜態方法引用來獲取每個字符串的長度。
String::length
在第三個測試中,我們使用的是實例方法引用。
ClassMate::getName
解釋
① map 方法是映射的意思。
② forEach 方式是遍歷每一個元素。
③ ClassMate 是一個包含 id 和 name 的簡單 po 類。
通過上面這個例子,基本上我們就知道怎么使用方法引用了。下面我們進行一個小的總結。
總結
① 使用方法
類名::方法名
② 方法可以是:靜態方法,實例方法
構造函數引用在上面我們講了方法引用的基本使用方法,其實除了方法引用以外,還有構造函數引用,回想一下,以前我們創建對象是怎么做?是不是需要 new 一個對象呢,那么現在用構造函數引用又是怎么做的呢?
下面我們用一個例子講解一下,在這個例子中,對象還是使用上面的 ClassMate。
/** * @return void * @Author ouyangsihai * @Description 構造函數引用測試 * @Date 10:23 2019/5/14 * @Param [] **/ @Test public void test_method_reference2() { //使用lambda表達式 Stream.of("A", "BB", "CCC", "DDDD", "FFFFF") .map(s -> new ClassMate(s)) //lambda .collect(Collectors.toList()); //使用構造函數引用 Stream.of("A", "BB", "CCC", "DDDD", "FFFFF") .map(ClassMate::new) //構造函數引用,由上下文決定用哪一個構造函數 .collect(Collectors.toList()); }
① 第一個我們使用的是 lambda 表達式進行創建對象的 s -> new ClassMate(s)。
② 第二個我們使用的是構造函數引用創建對象的 ClassMate::new 。
③ 我們發現構造函數引用:類名::new ,然后對于使用哪一個構造函數是由上下文決定的,比如有一個參數和兩個參數和無參數的構造函數,會自動確定用哪一個。
在 Java 8 之前的接口是不能有實現的,只能定義抽象方法,然而,在 Java 8 以后,增加了一個新的功能,可以添加實現,可以定義默認方法,可以定義靜態方法。
函數式接口什么是函數式接口呢?
這個名詞在 Java 中以前是很少聽到的,但是正是有了 Java 8 的橫空出世,函數式編程也變得熟悉了。
在一個接口中我們以 @FunctionalInterface 注解聲明一個接口,并且接口中只有一個抽象方法,那么我們就叫做這是一個函數式接口。
/** * @ClassName FunctionalInterfaceTest * @Description * @Author 歐陽思海 * @Date 2019/5/14 10:39 * @Version 1.0 **/ @FunctionalInterface public interface FunctionalInterfaceTest { //繼承接口后,又加了新的抽象方法,這個接口就不再是函數式接口 void test(String s); }
① 上面的接口中只有一個抽象方法,所以這是一個函數式接口。
② 如果上面接口中再加一個抽象方法,那么就不是函數式接口了。
下面,我們再通過繼承來繼承這個接口。
/** * @ClassName FunctionalTest * @Description * @Author 歐陽思海 * @Date 2019/5/17 17:26 * @Version 1.0 **/ public interface FunctionalTest extends FunctionalInterfaceTest{ int test2(); }
① 我們繼承了上面的接口,并且加了一個 test2 方法。
② 這里注意,如果一個接口集成現有的函數式接口后,又加了其他的抽象方法,這個接口就不是函數式接口了。
默認方法很簡單,用 default 聲明即可。
/** * @ClassName FunctionalInterfaceTest * @Description * @Author 歐陽思海 * @Date 2019/5/14 10:39 * @Version 1.0 **/ @FunctionalInterface public interface FunctionalInterfaceTest { //繼承接口后,又加了新的抽象方法,這個接口就不再是函數式接口 void test(String s); //默認方法 default String getStr(){ return null; } }
① 在接口中添加了一個默認方法。并且實現了方法。
靜態方法默認方法很簡單,用 static 聲明即可。
/** * @ClassName FunctionalInterfaceTest * @Description * @Author 歐陽思海 * @Date 2019/5/14 10:39 * @Version 1.0 **/ @FunctionalInterface public interface FunctionalInterfaceTest { //繼承接口后,又加了新的抽象方法,這個接口就不再是函數式接口 void test(String s); //靜態方法 static String getStr2(){ return null; } //錯誤用法 default static String getStr3(){ return null; } }
① 實現的靜態方法,用 static 聲明。
② 注意不能同時使用 default 和 static 聲明。
在這篇文章中,我們講了 lambda 表達式、方法引用、函數式接口、接口中的靜態方法、接口中的默認方法的使用。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/74858.html
摘要:上一篇小樂介紹了新特性函數式接口,大家可以點擊回顧。中引入方法引用新特性用于簡化應用對象方法的調用,方法引用是用來直接訪問類或者實例的已經存在的方法或者構造方法。方法引用是一種更簡潔易懂的表達式。 上一篇小樂介紹了《Java8新特性-函數式接口》,大家可以點擊回顧。這篇文章將接著介紹Java8新特性之方法引用。 Java8 中引入方法引用新特性,用于簡化應用對象方法的調用,?方法引用是...
摘要:大家好,我是樂字節的小樂,上一次我們說到了核心特性之函數式接口,接下來我們繼續了解又一核心特性方法引用。方法引用是一種更簡潔易懂的表達式。感謝光臨閱讀小樂的,敬請關注樂字節后續將繼續講述等前沿知識技術。 大家好,我是樂字節的小樂,上一次我們說到了Java8核心特性之函數式接口,接下來我們繼續了解Java8又一核心特性——方法引用。 showImg(https://segmentfaul...
摘要:實際上方法引用是表達式的一種語法糖。小結本篇全面介紹了方法引用的四種使用方式,且每種方式都有對應一個示例來幫助大家理解。 上一篇我們詳細介紹了Optional類用來避免空指針問題,本篇我們全面了解一下Java8中的方法引用特性。方法引用是lambda表達式的一種特殊形式,如果正好有某個方法滿足一個lambda表達式的形式,那就可以將這個lambda表達式用方法引用的方式表示,但是如果這...
摘要:一表達式匿名內部類最大的問題在于其冗余的語法,比如前面的中五行代碼僅有一行是在執行任務??偨Y基于詞法作用域的理念,表達式不可以掩蓋任何其所在上下文的局部變量。 轉載請注明出處:https://zhuanlan.zhihu.com/p/20540175 在介紹Lambda表達式之前,我們先來看只有單個方法的Interface(通常我們稱之為回調接口): public interface...
摘要:表達式體現了函數式編程的思想,即一個函數亦可以作為另一個函數參數和返回值,使用了函數作參數返回值的函數被稱為高階函數。對流對象進行及早求值,返回值不在是一個對象。 Java8主要的改變是為集合框架增加了流的概念,提高了集合的抽象層次。相比于舊有框架直接操作數據的內部處理方式,流+高階函數的外部處理方式對數據封裝更好。同時流的概念使得對并發編程支持更強。 在語法上Java8提供了Lamb...
閱讀 3415·2021-11-25 09:43
閱讀 3470·2021-11-19 09:40
閱讀 2474·2021-10-14 09:48
閱讀 1290·2021-09-09 11:39
閱讀 1929·2019-08-30 15:54
閱讀 2829·2019-08-30 15:44
閱讀 2002·2019-08-29 13:12
閱讀 1548·2019-08-29 12:59