Java8方法引用及構(gòu)造方法引用原理實(shí)例解析
如果不熟悉Java8新特性的小伙伴,初次看到函數(shù)式接口寫(xiě)出的代碼可能會(huì)是一種懵逼的狀態(tài),我是誰(shuí),我在哪,我可能學(xué)了假的Java,(・∀・(・∀・(・∀・*),但是語(yǔ)言都是在進(jìn)步的,就好比面向?qū)ο蟮恼Z(yǔ)言Java也可以寫(xiě)出優(yōu)雅的函數(shù)式調(diào)用,學(xué)習(xí)的過(guò)程并不復(fù)雜,當(dāng)你學(xué)會(huì)了Java8中函數(shù)式編程的新特性,你一定會(huì)對(duì)他愛(ài)不釋手的。下面介紹一下基于Lambda表達(dá)式簡(jiǎn)寫(xiě)的兩種引用。避免再次看到這種代碼時(shí)的尷尬😅。
方法引用
方法引用,一般包含下面三種寫(xiě)法,傳統(tǒng)的寫(xiě)法我們可能都是通過(guò)對(duì)象.去調(diào)用實(shí)例方法或使用類(lèi).調(diào)用靜態(tài)方法,但是學(xué)完方法引用后,就可以可以使用這三種方式去調(diào)用方法,但是要符合一定的規(guī)則。
對(duì)象::實(shí)例方法
/** * 對(duì)象調(diào)用實(shí)例方法 */ public static void objMethod(){ List<Integer> list = new ArrayList<> (); list.add(1); list.add(2); list.add(3); list.forEach((i)->{ PrintStream out = System.out; Consumer<Integer> consumer = out::println; consumer.accept(i); }); list.forEach(System.out::println); }
最常用的System.out.println
類(lèi)::實(shí)例方法
/** * 判斷兩個(gè)字符串是否相同 * * @param str1 * @param str2 * @return */ public static boolean isEqual(String str1, String str2) { BiPredicate<String,String> b = (s1,s2)->s1.equals(str2); ① BiPredicate<String, String> bp = String::equals; return bp.test(str1, str2); }
類(lèi)::靜態(tài)方法
/** * 比較大小 * @param x * @param y * @return */ public static boolean compareValue(int x, int y){ Comparator<Integer> compare = Integer::compare; ② return compare.compare(x, y) > 0; }
其實(shí)不管是哪一種調(diào)用方式都是有規(guī)律可循的,這里總結(jié)一下在使用Lambda表達(dá)式的過(guò)程中符合什么樣的規(guī)則才可以使用方法引用的模式去寫(xiě)。
Lambda體中調(diào)用方法的參數(shù)列表與返回值類(lèi)型,要與函數(shù)式接口中抽象方法的函數(shù)列表和返回值類(lèi)型保持一致 Integer::compare ②
Lambda參數(shù)列表中的第一參數(shù)是實(shí)例方法的調(diào)用者,而第二個(gè)參數(shù)是實(shí)例方法的參數(shù)時(shí) 可以使用ClassName::method ①
構(gòu)造方法引用#
簡(jiǎn)稱(chēng)花式new對(duì)象,一個(gè)簡(jiǎn)單的new對(duì)象也要寫(xiě)的高端、大氣、上檔次😄,既可以掌握新知識(shí),又可以ZB,趕緊學(xué)習(xí)吧。
ClassName::new
資源類(lèi):
public class Apple { private String color; private double weight; public Apple(){ } public Apple(String color) { this.color = color; } public Apple(double weight) { this.weight = weight; } public Apple(String color, double weight) { this.color = color; this.weight = weight; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } @Override public String toString() { return "Apple{" + "color='" + color + '\'' + ", weight=" + weight + '}'; } }
測(cè)試代碼:
public static void main(String[] args) { //無(wú)參構(gòu)造 //Supplier<Apple> supplier = () -> new Apple(); Lambda表達(dá)式寫(xiě)法 Supplier<Apple> supplier = Apple::new; Apple apple = supplier.get(); System.out.println("NoArgsConstructor: "+apple); //有參構(gòu)造 //Function<Double,Apple> function = (x) -> new Apple(x); Lambda表達(dá)式寫(xiě)法 // 構(gòu)造引用 Function<Double,Apple> function = Apple::new; Apple apply = function.apply(1.0); System.out.println("OneArgsConstructor: "+apply); BiFunction<String,Double,Apple> bf = Apple::new; Apple bi = bf.apply("Red", 2.0); System.out.println("TwoArgsConstructor: "+bi); }
輸出結(jié)果:
NoArgsConstructor: Apple{color='null', weight=0.0}
OneArgsConstructor: Apple{color='null', weight=1.0}
TwoArgsConstructor: Apple{color='Red', weight=2.0}
當(dāng)構(gòu)造方法無(wú)參時(shí)使用Supplier,有一個(gè)參數(shù)時(shí)使用Function,兩個(gè)參數(shù)時(shí)使用BiFunction。這里很容易得出一個(gè)規(guī)律,當(dāng)使用構(gòu)造方法引用時(shí),函數(shù)式接口的參數(shù)列表需要和構(gòu)造方法的參數(shù)列表保持一致。
我們也可以用這些函數(shù)式接口改寫(xiě)傳統(tǒng)的創(chuàng)建數(shù)組的方式,初始化一個(gè)指定長(zhǎng)度的數(shù)組,比如
Function<Integer,String[]> fun = String[]::new;
String[] strArr = fun.apply(10);
也可以這樣寫(xiě):
public static <T> T[] initArray(int num, Function<Integer,T[]> function){ return function.apply(num); }
調(diào)用:
Copy
Apple[] strings = initArray(10, x -> new Apple[x]);
System.out.println(strings.length);
疑惑
根據(jù)傳入的參數(shù)返回指定的對(duì)象數(shù)組引用,不過(guò)這樣還不如直接創(chuàng)建。不知道讀者有沒(méi)有考慮這里為什么不可以用一個(gè)泛型來(lái)new,那樣就可以創(chuàng)建一個(gè)通用數(shù)組引用,但是Java中的泛型是偽泛型,在編譯器就會(huì)進(jìn)行泛型擦除,所以不能通過(guò)new關(guān)鍵字來(lái)創(chuàng)建一個(gè)泛型對(duì)象,具體內(nèi)容可以在查閱其他資料了解泛型以及泛型擦除的原理,這里不做深究。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java跳臺(tái)階實(shí)現(xiàn)思路和代碼
今天小編就為大家分享一篇關(guān)于Java跳臺(tái)階實(shí)現(xiàn)思路和代碼,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01詳解Java并發(fā)編程之內(nèi)置鎖(synchronized)
這篇文章主要介紹了Java并發(fā)編程之內(nèi)置鎖(synchronized)的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03高分面試分析jvm如何實(shí)現(xiàn)多態(tài)
這篇文章主要介紹了講解了在面試中jvm如何實(shí)現(xiàn)多態(tài),怎樣回答才能得到高分的問(wèn)題分析,有需要的朋友可以借鑒參考下,祝大家早日升職加薪多多進(jìn)步2022-01-01講解Java設(shè)計(jì)模式編程中的建造者模式與原型模式
這篇文章主要介紹了Java設(shè)計(jì)模式編程中的建造者模式與原型模式,設(shè)計(jì)模式有利于團(tuán)隊(duì)開(kāi)發(fā)過(guò)程中的代碼維護(hù),需要的朋友可以參考下2016-02-02java題解Leetcode 8字符串轉(zhuǎn)換整數(shù)
這篇文章主要為大家介紹了java題解Leetcode 8字符串轉(zhuǎn)換整數(shù)實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06Java特性?Lambda?表達(dá)式和函數(shù)式接口
這篇文章主要介紹了Java特性?Lambda?表達(dá)式和函數(shù)式接口,Lambda表達(dá)式基于函數(shù)式編程思想,也可以稱(chēng)為閉包,是Java?8引入的重要新特性,?Lambda允許把函數(shù)作為一個(gè)方法的參數(shù)2022-06-06