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