1违柏、方法引用基本介紹
主要對Lambda表達式的優(yōu)化
在使用Lambda表達式的時候为肮,實際上傳遞進去的是代碼就是一種解決方案,拿什么參數做什么需求涡真,那么考慮一種情況,如果我們在Lambda中所指的操作方案肾筐,已經有地方有相同方案哆料,是否需重復?
Lambda要有函數式接口吗铐,定義一個函數式接口
package com.company.demo05LambdaTest;
/**
* @author 杜艷艷
* @version 1.0
* @date 2020/12/29 16:37
* 定義一個打印的函數式接口,
*/
@FunctionalInterface
public interface Printable {
//打印字符串的抽象方法
void print(String s);
}
定義一個類剧劝。
package com.company.demo05LambdaTest;
/**
* @author 杜艷艷
* @version 1.0
* @date 2020/12/29 16:39
*/
public class Demo01Printable {
//定義一個方法,參數傳printable接口抓歼。對字符串打印
public static void printString(Printable p ){
p.print("helloword");
}
public static void main(String[] args) {
//調用printstring方法 ,參數Printable是一個函數式接口讥此,可以傳遞lambda表達式
printString((s)->{
System.out.println(s); //helloword
});
/*
分析
lambda 表達式的目的,打印參數傳遞的字符串谣妻,把參數s傳遞給System.out對象萄喳,調用out對象的方法println,對字符串輸出
注意:
1蹋半、System.out對象已經存在他巨,
2、調用其方法println已經存在
所以可以用方法引用優(yōu)化lambda
可以使用System.out直接引用(調用)println方法 ,取代Lambda染突, 對字符串輸出捻爷,參數省略
:: 是方法引用的運算符,表達式是方法引用表達式
兩種寫法效果一樣份企,第二種更簡潔
注意:
Lambda中傳遞的參數一定是方法引用中的那個方法可以接收的類型也榄,否則拋異常
*/
printString(System.out::println); //helloword
}
}
方法引用符
2、方法引用-通過對象名引用成員方法
前提: 類存在司志,靜態(tài)方法存在
1甜紫、對象名要有實例 化的對象,所以要建一個類骂远,實例對象囚霸, 類中定義一個成員方法, 通過類創(chuàng)建一個對象激才,來引用里面的成員方法
類MethodRerObject
package com.company.demo06ObjectMethod;
/**
* @author 杜艷艷
* @version 1.0
* @date 2020/12/30 16:48
*/
public class MethodRerObject {
//定義一個成員方法拓型,傳遞字符串,按照大寫輸出
public void printUpString(String str){
System.out.println(str.toUpperCase());
}
}
2瘸恼、函數式接口
package com.company.demo06ObjectMethod;
/**
* @author 杜艷艷
* @version 1.0
* @date 2020/12/29 16:37
* 定義一個打印的函數式接口,
*/
@FunctionalInterface
public interface Printable {
//打印字符串的抽象方法
void print(String s);
}
3吨述、測試類
package com.company.demo06ObjectMethod;
/**
* @author 杜艷艷
* @version 1.0
* @date 2020/12/30 16:51
* 通過對象名引用成員方法
* 使用前提:對象名存在,成員方法存在钞脂,就可以使用對象名引用成員方法
*/
public class Demo01ObjectMethodRer {
//定義一個方法揣云。方法的參數傳遞Printable接口
public static void printString(Printable p){
p.print("hello");
}
public static void main(String[] args) {
//調用printString ,方法的參數是函數式接口,可以傳遞lambda 表達式
printString((s)->{
//創(chuàng)建MethodRerObject對象
MethodRerObject obj = new MethodRerObject();
//調用對象中的成員方法printUpString冰啃,把字符串按照大寫輸出
obj.printUpString(s); //HELLO
});
/*使用方法引用優(yōu)化lambda
對象MethodRerObject已經存在邓夕, 成員方法也存在printUpString
所以可以用對象名來引用成員方法
*/
//創(chuàng)建MethodRerObject對象
MethodRerObject obj2 = new MethodRerObject();
printString(obj2::printUpString); //HELLO
}
}
3、方法引用-通過類名引用靜態(tài)成員方法
由于在類中java.lang.Math中已經存在了靜態(tài)方法abs阎毅,所以需要通過lambda 調用該方法時焚刚,有兩種寫法,首先是函數式接口扇调,使用lambda 矿咕, 一種是類名引用靜態(tài)方法
函數式接口
package com.company.demo07StaticMethod;
/**
* @author 杜艷艷
* @version 1.0
* @date 2020/12/30 17:08
*/
@FunctionalInterface
public interface Calcable {
//定義一個抽象方法,傳遞一個整數狼钮,對整數進行絕對值計算碳柱,并返回
public int calAbs(int number);
}
測試類
package com.company.demo07StaticMethod;
/**
* @author 杜艷艷
* @version 1.0
* @date 2020/12/30 17:11
* 通過類名引用靜態(tài)成員方法,使用前提:類名存在熬芜,靜態(tài)成員方法存在莲镣;就可以直接用類名引用靜態(tài)成員方法
*/
public class Demo01StaticMethodRer {
//定義一個方法,方法的參數傳遞要計算絕對值的整數 和 函數式接口Calcable
public static int method(int number,Calcable c){
return c.calAbs(number);
}
public static void main(String[] args) {
//調用method 方法涎拉,傳遞計算絕對值的整數 和 Lambda表達式
int num = method(-10,(n)->{
//對參數進行絕對值的計算瑞侮,并返回結果
return Math.abs(n);
});
System.out.println(num); //10
/*通過類名引用靜態(tài)成員方法的圆。優(yōu)化lambda表達式
Math 存在。abs 計算絕對值的靜態(tài)成員方法存在
所以可以直接通過類名引用靜態(tài)方法
*/
int num2 = method(-10, Math::abs);
System.out.println(num2); //10
}
}
4半火、方法引用-通過super引用父類的成員方法
如果存在繼承關系越妈,當Lambda中需要出現super調用時,也可以使用方法引用進行替代
前提: 有子父類繼承關系钮糖,有函數式接口梅掠,父類有成員方法
例子
函數式接口
package con.day13.demo05.SuperMethodReference;
/*
定義一個見面的函數式接口
*/
@FunctionalInterface
public interface Greetable {
//定義一個見面的方法
void greet();
}
父類
package con.day13.demo05.SuperMethodReference;
/*
定義父類
*/
public class Human {
//定義一個sayhello 的方法
public void sayHello(){
System.out.println("父類human的sayHellO");
}
}
子類以及主方法
package con.day13.demo05.SuperMethodReference;
/*
定義子類
*/
public class Man extends Human{
//重寫父類sayHello的方法
@Override
public void sayHello() {
System.out.println("我是子類");
}
//定義一個方法參數傳遞Greetable接口
public void method(Greetable g){
g.greet();
}
public void show(){
//調用method 方法,方法的參數是函數式接口藐鹤,可傳遞Lambda
/* method(()->{
//創(chuàng)建父類對象
Human h = new Human();
//調用父類的sayHello
h.sayHello();
});*/
//因為有子父類關系,可以存在一個關鍵字super 所以我們可以直接用super調用父類的成員方法
/* method(()->{
super.sayHello(); //父類human的sayHellO
});*/
//繼續(xù)簡化赂韵, 使用super引用父類的成員方法娱节, super 已經存在,sayHello 已經存在祭示,
//所以可直接使用super引用父類的成員方法
//父類human的sayHellO
method(super::sayHello);
}
public static void main(String[] args) {
new Man().show(); //父類human的sayHellO
}
}
5肄满、方法引用,通過this引用本類的成員
this
函數式接口
package con.day13.demo05.ThisMethodReference;
/*
定義一個函數式接口
*/
@FunctionalInterface
public interface Richable {
//想買什么就買什么的方法
void buy();
}
方法:
package con.day13.demo05.ThisMethodReference;
/*
通過this引用本類的成員方法
*/
public class Husband {
//定義一個買房子的方法
public void buyHouse(){
System.out.println("買到房子啦");
}
//定義結婚方法质涛,參數傳遞Richable接口
public void marry(Richable r){
r.buy();
}
/* //定義一個非常高興的方法
public void soHappy(){
//調用結婚方法稠歉。方法的參數Richable 是一個函數式接口,用Lambda
marry(()->{
//使用this.成員方法汇陆,調用本類買房子的方法
this.buyHouse(); //買到房子啦
});
}*/
//簡化怒炸, 方法引用
//定義一個非常高興的方法
public void soHappy(){
//調用結婚方法。方法的參數Richable 是一個函數式接口毡代,用Lambda
marry(this::buyHouse); //買到房子啦;
}
public static void main(String[] args) {
Husband husband = new Husband();
husband.soHappy();
}
}
6阅羹、 方法引用-類的構造器引用
類
Person 類
package con.day13.demo05.ConstructorMethodReference;
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
函數式接口
package con.day13.demo05.ConstructorMethodReference;
//創(chuàng)建Perso對象的函數式接口
@FunctionalInterface
public interface PersonBuilder {
//定義一個方法,根據傳遞的姓名教寂,創(chuàng)建Person 對象返回
Person builderPerson(String name);
}
方法類
package con.day13.demo05.ConstructorMethodReference;
/*
類的構造器引用
*/
public class Demo {
//定義一個方法捏鱼,參數傳遞姓名和PersonBuilder接口,方法中通過姓名創(chuàng)建Person對象
public static void pringName(String name, PersonBuilder pb){
Person person = pb.builderPerson(name);
System.out.println(person.getName()); //迪麗熱巴
}
/* public static void main(String[] args) {
//調用pringName方法酪耕,方法的參數是PersonBuilder 导梆,函數式接口,用Lambda
pringName("迪麗熱巴",(String name)->{
return new Person(name);
});
}*/
/*使用方法引用迂烁,優(yōu)化
構造方法new Person(String name)已知
創(chuàng)建對象已經new
就可以使用Person引用new創(chuàng)建對象
*/
public static void main(String[] args) {
//調用pringName方法看尼,方法的參數是PersonBuilder ,函數式接口盟步,用Lambda
pringName("迪麗熱巴", Person::new);
}
}