方法引用的学习
文章目錄
- 通過對象名稱引用成員方法
- 演示代碼一
- 演示代碼二
- 通過類名稱引用靜態(tài)方法
- 通過 super 引用成員方法
- 通過 this 引用本類的成員方法
- 類的構(gòu)造器引用
- 數(shù)組的構(gòu)造器引用
通過對象名稱引用成員方法
演示代碼一
package priv.lwx.javaprac.methodreference; public class Demo01Printable {public static void main(String[] args) {// 調(diào)用方法printStringprintString(str -> System.out.println(str));// 上面的Lambda表達(dá)的函數(shù)方案就是接收一個(gè)字符串,然后打印輸出,這個(gè)業(yè)務(wù)邏輯和方法println完全相同,// 所以直接引用這個(gè)方法即可,因此可以改成“方法引用”表達(dá)式printString(System.out::println);}// 聲明定義一個(gè)方法,傳遞一個(gè)Printable對象,打印字符串public static void printString(Printable p) {p.print("Hello World!");} }問題分析:
main 方法中通過 Lambda 表達(dá)式指定了函數(shù)式接口 Printable 的 print 方法的具體方案為:拿到字符串后,在控制臺打印輸出。而將字符串在控制臺打印輸出的操作方案,已經(jīng)有現(xiàn)成的實(shí)現(xiàn),那就是 System.out 對象中的 println(String) 方法。既然 Lambda 希望做的事情就是調(diào)用 println(String) 方法,那又何必再寫重復(fù)邏輯呢?
于是引入新的概念,叫“方法引用”,可以直接省略 Lambda 的語法格式,“引用” System.out 對象中的 println(String) 方法就可以了,方法引用表達(dá)式為:System.out::println。
方法引用的語法格式:對象 :: 方法名。
雙冒號 :: 稱為引用運(yùn)算符,而它所在的表達(dá)式稱為“方法引用”。如果 Lambda 要表達(dá)的函數(shù)方案已經(jīng)存在于某個(gè)方法的實(shí)現(xiàn)中,那么則可以通過雙冒號來引用該方法作為 Lambda 的替代者。
注:Lambda 表達(dá)式中傳遞的參數(shù)一定是方法引用中的那個(gè)方法可以接收的類型,否則會(huì)拋出異常。
演示代碼二
MethodRefViaObject:
package priv.lwx.javaprac.methodreference;/*** @ClassName MethodRefViaObject* @Description 聲明定義一個(gè)類,其中含有一個(gè)成員方法,用于以大寫形式打印英文字符串* @Author liaowenxiong* @Version 1.0* @date 2021/9/13 上午8:25*/ public class MethodRefViaObject {// 聲明定義一個(gè)方法,以大寫形式打印輸出接收到的英文字符串public void printStringUppercase(String str) {System.out.println(str.toUpperCase());} }Printable:
package priv.lwx.javaprac.methodreference;/*** @InterfaceNAME Printable* @Description 聲明定義一個(gè)打印的函數(shù)式接口* @Author liaowenxiong* @Date 2021/9/12 下午10:07* @Version 1.0*/ @FunctionalInterface public interface Printable {// 打印字符串的抽象方法public abstract void print(String str); }Demo02MethodRefViaObject:
package priv.lwx.javaprac.methodreference;/*** @ClassName Demo02MethodRefViaObject* @Description 通過對象名稱引用成員方法的演示代碼* @Author liaowenxiong* @Version 1.0* @date 2021/9/13 上午8:28*/ public class Demo02MethodRefViaObject {public static void main(String[] args) {printString(s -> { // 這是對函數(shù)式接口的抽象方法print的實(shí)現(xiàn)代碼MethodRefViaObject mrvo = new MethodRefViaObject();mrvo.printStringUppercase(s);});/*分析:已經(jīng)存在一個(gè)類MethodRefViaObject,該類含有方法printStringUppercase,該方法就是用來將字符串以大寫形式打印輸出,而Lambda表達(dá)式的函數(shù)方案就是將字符串以大寫形式打印輸出,所以可以直接引用此方法*/// 必須先創(chuàng)建該對象MethodRefViaObject mrvo = new MethodRefViaObject();// 通過對象名稱引用成員方法printString(mrvo::printStringUppercase);// 其實(shí)方法引用,只是省略了參數(shù)而已}// 定義一個(gè)方法,方法參數(shù)是函數(shù)式接口Printable類型public static void printString(Printable p) {p.print("Hello World!");} }通過類名稱引用靜態(tài)方法
Calculable:
package priv.lwx.javaprac.methodreference;/*** @InterfaceNAME Calculable* @Description 聲明定義一個(gè)函數(shù)式接口,該接口僅有一個(gè)用于計(jì)算絕對值的抽象方法* @Author liaowenxiong* @Date 2021/9/13 上午11:36* @Version 1.0*/ public interface Calculable {// 聲明一個(gè)抽象方法,計(jì)算整數(shù)的絕對值并返回int calcAbs(int i); }Demo03MethodRefViaClassName:
package priv.lwx.javaprac.methodreference;/*** @ClassName Demo03MethodRefViaClassName* @Description 通過類名引用靜態(tài)方法* @Author liaowenxiong* @Version 1.0* @date 2021/9/13 下午2:30*/ public class Demo03MethodRefViaClassName {public static void main(String[] args) {// 調(diào)用方法calcAbs,傳遞一個(gè)負(fù)數(shù)-10,和一個(gè)Lambda表達(dá)式,計(jì)算負(fù)數(shù)的絕對值int absVal1 = calcAbs(-10, i -> Math.abs(i));// Lambda表達(dá)式就是計(jì)算絕對值,所以直接引用Math的方法abs即可System.out.println(absVal1);// 改成方法引用表達(dá)式。上述的Lambda表達(dá)式就是計(jì)算絕對值,所以直接引用Math的方法abs即可int absVal2 = calcAbs(-10, Math::abs);System.out.println(absVal2);}// 聲明定義一個(gè)方法,參數(shù)傳遞一個(gè)要計(jì)算絕對值的整數(shù),和Calculable對象public static int calcAbs(int i, Calculable cal) {return cal.calcAbs(i);} }通過 super 引用成員方法
Greetable:
package priv.lwx.javaprac.methodreference;/*** @InterfaceNAME Greetable* @Description 聲明定義一個(gè)打招呼的函數(shù)式接口* @Author liaowenxiong* @Date 2021/9/13 下午3:12* @Version 1.0*/ @FunctionalInterface public interface Greetable {public abstract void greet(); }Person:
package priv.lwx.javaprac.methodreference;/*** @ClassName Person* @Description 定義一個(gè)父類* @Author liaowenxiong* @Version 1.0* @date 2021/9/13 下午3:16*/ public class Person {public void sayHello() {System.out.println("Hello,我是人類!");} }WhitePerson:
package priv.lwx.javaprac.methodreference;/*** @ClassName WhitePerson* @Description 聲明定義一個(gè)類,繼承自Person* @Author liaowenxiong* @Version 1.0* @date 2021/9/13 下午3:15*/ public class WhitePerson extends Person{public static void main(String[] args) {new WhitePerson().show();}@Overridepublic void sayHello() {System.out.println("Hello,我是白人!");}// 聲明定義一個(gè)方法,該方法傳遞一個(gè)Greetable對象public void method(Greetable g) {g.greet();}public void show() {// 傳遞Lambda表達(dá)式,函數(shù)中構(gòu)造父類對象,調(diào)用父類的sayHello方法method(()-> {Person person = new Person();person.sayHello();});// 可以改成使用關(guān)鍵字super來調(diào)用父類的成員方法method(()->{super.sayHello();});// 使用super引用父類的成員方法;// 注意:show方法所在類是子類,才能使用super引用父類的成員方法method(super::sayHello);} }通過 this 引用本類的成員方法
Richable:
package priv.lwx.javaprac.methodreference;/*** @InterfaceNAME Richable* @Description 聲明定義一個(gè)函數(shù)式接口Richable* @Author liaowenxiong* @Date 2021/9/13 下午4:04* @Version 1.0*/ @FunctionalInterface public interface Richable {// 聲明一個(gè)抽象方法,想買啥就買啥public abstract void buy(); }Husband:
package priv.lwx.javaprac.methodreference;/*** @ClassName Husband* @Description 聲明定義一個(gè)類Husband,定義結(jié)婚、買房等方法* @Author liaowenxiong* @Version 1.0* @date 2021/9/13 下午4:04*/ public class Husband {public static void main(String[] args) {new Husband().soHappy();}public void buyHouse() {System.out.println("北京二環(huán)內(nèi)購買一套四合院");}public static void buyCar() {System.out.println("購買奔馳車一輛");}public void marry(Richable r) {r.buy();}public void soHappy() {marry(()->{// 使用【this.成員方法】調(diào)用本類的成員方法this.buyHouse();// this表示本類,編譯成 Husband$buyHouse()// this.buyCar();});// 使用方法引用優(yōu)化Lambda表達(dá)式marry(this::buyHouse);}}類的構(gòu)造器引用
類構(gòu)造器引用表達(dá)式:類名::new
Person:
package priv.lwx.javaprac.methodreference;/*** @ClassName Person* @Description 定義一個(gè)父類* @Author liaowenxiong* @Version 1.0* @date 2021/9/13 下午3:16*/ public class Person {public String name;public Person() {}public Person(String name) {this.name = name;}public void sayHello() {System.out.println("Hello,我是人類!");}public String getName() {return name;}public void setName(String name) {this.name = name;} }PersonBuilder:
package priv.lwx.javaprac.methodreference;/*** @ClassName PersonBuilder* @Description 定義一個(gè)創(chuàng)建Person對象的函數(shù)式接口* @Author liaowenxiong* @Version 1.0* @date 2021/9/13 下午7:36*/ public interface PersonBuilder {// 聲明一個(gè)抽象方法,根據(jù)傳入的字符串,創(chuàng)建Person對象public abstract Person buildPerson(String name); }Demo05Person:
package priv.lwx.javaprac.methodreference;/*** @ClassName Demo05Person* @Description 類的構(gòu)造器引用* @Author liaowenxiong* @Version 1.0* @date 2021/9/13 下午7:46*/ public class Demo05Person {public static void main(String[] args) {// 調(diào)用方法buildPerson,傳入姓名和PersonBuilder對象,創(chuàng)建Person對象Person person1 = buildPerson("楊思敏", name -> new Person(name));System.out.println(person1.getName());// 使用方法引用表達(dá)式來優(yōu)化,通過類名引用構(gòu)造方法,格式:【類名::new】Person person2 = buildPerson("李瓶兒", Person::new); // 因?yàn)楹瘮?shù)式接口的抽象方法buildPerson(String),需要傳入一個(gè)字符串參數(shù),可以推導(dǎo)出調(diào)用的是new Person(String)構(gòu)造器System.out.println(person2.getName());}// 聲明定義一個(gè)方法,傳入姓名和PersonBuilder對象,方法通過姓名創(chuàng)建Person對象public static Person buildPerson(String name, PersonBuilder pb) {// 通過調(diào)PersonBuilder對象的buildPerson方法創(chuàng)建Person對象Person person = pb.buildPerson(name);return person;}}數(shù)組的構(gòu)造器引用
ArrayBuilder:
package priv.lwx.javaprac.methodreference;/*** @InterfaceNAME ArrayBuilder* @Description 聲明定義一個(gè)創(chuàng)建int類型數(shù)組的函數(shù)式接口* @Author liaowenxiong* @Date 2021/9/13 下午9:21* @Version 1.0*/ @FunctionalInterface public interface ArrayBuilder {int[] buildArray(int length); }Demo06ArrayConstructionMethodRef:
package priv.lwx.javaprac.methodreference;/*** @ClassName Demo06ArrayConstructionMethodRef* @Description 數(shù)組構(gòu)造器引用的演示代碼* @Author liaowenxiong* @Version 1.0* @date 2021/9/13 下午10:01*/ public class Demo06ArrayConstructionMethodRef {public static void main(String[] args) {// 調(diào)方法arrayBuilder,傳入數(shù)組長度和Lambda表達(dá)式,構(gòu)造一個(gè)int數(shù)組int[] intArray = createArray(5, i -> new int[i]);System.out.println(intArray.length);// 使用方法引用表達(dá)式優(yōu)化,即引用數(shù)組的構(gòu)造方法int[] intArray2 = createArray(6, int[]::new); // 引用數(shù)組構(gòu)造器,數(shù)組的長度可以通過createArray方法中的ab.buildArray(length)推導(dǎo)出來System.out.println(intArray2.length);}// 定義一個(gè)方法,傳遞數(shù)組長度和函數(shù)式接口對象,構(gòu)造一個(gè)指定長度的int數(shù)組public static int[] createArray(int length, ArrayBuilder ab) {return ab.buildArray(length);}}總結(jié)
- 上一篇: chrome怎么设置中文(chrome浏
- 下一篇: 判断字符串是不是application/