雙冒號(hào)::為引用運(yùn)算符,而它所在的表達(dá)式被稱為方法引用。
/**
* 定義一個(gè)打印的函數(shù)式接口
*/
@FunctionalInterface
public interface Printable {
//定義一個(gè)字符串的抽象方法
void print(String s);
}
//定義一個(gè)方法,參數(shù)傳遞printable接口,對(duì)字符串進(jìn)行打印
public static void printString(Printable p){
p.print("hello world");
}
public static void main(String[] args) {
//調(diào)用printString方法,方法的參數(shù)printable是一個(gè)函數(shù)式接口,所以可以傳遞lambda表達(dá)式
printString((s)->{
System.out.println(s);
});
/**
* 分析:lambda表達(dá)式的目的,打印參數(shù)傳遞的字符串,把參數(shù)s傳遞給了System.out對(duì)象,
* 調(diào)用out對(duì)象中的方法println對(duì)字符串進(jìn)行了輸出
* 注意:System.out對(duì)象是已經(jīng)存在的;println方法也是已經(jīng)存在的。所以我們可以使用
* 方法引用來(lái)優(yōu)化lambda表達(dá)式,可以使用System.out方法直接引用(調(diào)用)println方法
*/
printString(System.out::println);
}
(1)通過(guò)對(duì)象名引用成員方法
/**
* 定義一個(gè)打印的函數(shù)式接口
*/
@FunctionalInterface
public interface Printable {
//定義一個(gè)字符串的抽象方法
void print(String s);
}
public class Demo02Method {
//定義一個(gè)成員方法,傳遞字符串,把字符串按照大寫(xiě)輸出
public void peintUpperCaseString(String str){
System.out.println(str.toUpperCase());
}
}
/**
* 通過(guò)對(duì)象名引用成員方法,使用前提是對(duì)象名已經(jīng)存在的,成員方法也是已經(jīng)存在的
*
*/
public class Demo02ObjectMethod {
//定義一個(gè)方法,方法的參數(shù)傳遞printable接口
public static void printString(Printable p){
p.print("hello");
}
public static void main(String[] args) {
//調(diào)用printString方法,方法的參數(shù)Printable是一個(gè)函數(shù)式接口,所以可以傳遞lambda表達(dá)式
printString((s)->{
//創(chuàng)建Demo02Method對(duì)象
Demo02Method obj = new Demo02Method();
//調(diào)用Demo02Method對(duì)象中的成員方法printUpperCaseString,把字符串按照大寫(xiě)輸出
obj.peintUpperCaseString(s);
});
/**
* 使用方法引用優(yōu)化lambda,對(duì)象是已經(jīng)存在的Demo02Method,
* 成員方法也是已經(jīng)存在的peintUpperCaseString,
* 所以我們可以使用對(duì)象名引用成員方法
*/
Demo02Method obj = new Demo02Method();
printString((obj::peintUpperCaseString));
}
}
(2)通過(guò)類名引用靜態(tài)成員方法
前提:類已經(jīng)存在,靜態(tài)成員方法也已經(jīng)存在,就可以通過(guò)類名直接引用靜態(tài)成員方法。
@FunctionalInterface
public interface Calcable {
//定義一個(gè)抽象方法,傳遞一個(gè)整數(shù),對(duì)整數(shù)進(jìn)行絕對(duì)值計(jì)算并返回
int calsAbs(int number);
}
public class Demo03StaticMethodReference {
//定義一個(gè)方法,方法的參數(shù)傳遞要計(jì)算絕對(duì)值的整數(shù)和函數(shù)式接口Calcable
public static int method(int number, Calcable c){
return c.calsAbs(number);
}
public static void main(String[] args) {
//調(diào)用method方法,傳遞計(jì)算絕對(duì)值的整數(shù)和lambda表達(dá)式
int num = method(-10,(n)->{
//對(duì)參數(shù)進(jìn)行絕對(duì)值的計(jì)算并返回結(jié)果
return Math.abs(n);
});
System.out.println(num);
/**
* 使用方法引用優(yōu)化lambda表達(dá)式
* Math類是存在的
* abs計(jì)算絕對(duì)值的靜態(tài)方法也是存在的
* 所以我們可以直接通過(guò)類名引用靜態(tài)方法
*/
int num2 = method(-10, Math::abs);
System.out.println(num2);
}
}
(3)通過(guò)super引用成員方法
/**
* 定義見(jiàn)面的函數(shù)式接口
*/
@FunctionalInterface
public interface Greetble {
//定義一個(gè)見(jiàn)面的方法
void greet();
}
/**
* 定義父類
*/
public class Human {
//定義一個(gè)sayHello的方法
public void sayHello(){
System.out.println("Hello,我是父類");
}
}
public class Man extends Human {
@Override
public void sayHello() {
System.out.println("hello,我是man");
}
//定義一個(gè)方法,參數(shù)傳遞Greetable接口
public void method(Greetble g){
g.greet();
}
public void show(){
//調(diào)用method方法,方法的參數(shù)Greetable接口是一個(gè)函數(shù)式接口,所以可以傳遞lambda
method(()->{
Human h = new Human();
h.sayHello();
});
//因?yàn)橛凶痈割愱P(guān)系,所以存在一個(gè)關(guān)鍵字super,代表父類,
// 所以我們可以直接使用super調(diào)用父類的成員方法
method(()->{
super.sayHello();
});
/**
* 使用super引用父類的成員方法,super是已經(jīng)存在的,父類的成員方法sayHello也是存在的
* 所以可以直接調(diào)用super引用父類的成員方法
*/
method(super::sayHello);
}
public static void main(String[] args) {
new Man().show();
}
}
(4)通過(guò)this引用成員方法
/**
* 定義一個(gè)富有的函數(shù)式接口
*/
public interface Richable {
//定義一個(gè)想買(mǎi)什么就買(mǎi)什么的方法
void buy();
}
/**
* 通過(guò)this引用本類的成員方法
*/
public class Husband {
//定義一個(gè)買(mǎi)房子的方法
public void buyHouse(){
System.out.println("北京二環(huán)內(nèi)買(mǎi)一套四合院");
}
//定義一個(gè)結(jié)婚的方法,參數(shù)傳遞Richable接口
public void marry(Richable r){
r.buy();
}
//定義一個(gè)非常高興的方法
public void soHappy(){
//調(diào)用結(jié)婚的方法
marry(()->{
this.buyHouse();
});
/**
* 使用放啊引用優(yōu)化lambda表達(dá)式
* this是已經(jīng)存在的,本類的成員方法buyHouse也是已經(jīng)存在的,
* 所以可以直接使用this引用本類的成員方法
*/
marry(this::soHappy);
}
public static void main(String[] args) {
new Husband().soHappy();
}
}
(5)類的構(gòu)造器的引用
構(gòu)造器的引用使用類名稱::new的格式表示
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;
}
}
/**
* 定義一個(gè)創(chuàng)建person對(duì)象的函數(shù)式接口
*/
public interface PersonBuilder {
//定義一個(gè)方法,根據(jù)傳遞的姓名,創(chuàng)建person對(duì)象返回
Person builderPerson(String name);
}
/**
* 類的構(gòu)造器引用
*/
public class DemoPerson {
//定義一個(gè)方法,參數(shù)傳遞姓名和PersonBuilder接口,方法中通過(guò)姓名創(chuàng)建Person對(duì)象
public static void printName(String name, PersonBuilder pb){
Person person = pb.builderPerson(name);
System.out.println(person.getName());
}
public static void main(String[] args) {
//調(diào)用printName方法,方法的參數(shù)PersonBuilder接口是一個(gè)函數(shù)式接口,可以傳遞lambda
printName("迪麗熱巴", (name)->{
return new Person(name);
});
/**
* 使用方法引用優(yōu)化lambda表達(dá)式
* 構(gòu)造方法new Person(String name)已知
* 創(chuàng)建對(duì)象已知new
* 就可以使用Person引用new創(chuàng)建對(duì)象
*/
printName("古力娜扎",Person::new);//使用Person的帶參構(gòu)造方法,通過(guò)傳遞的姓名創(chuàng)建對(duì)象
}
}
數(shù)組構(gòu)造器的引用
/**
* 定義一個(gè)創(chuàng)建數(shù)組的函數(shù)式接口
*/
@FunctionalInterface
public interface ArrayBuilder {
//定義一個(gè)創(chuàng)建int類型數(shù)組的方法,參數(shù)傳遞數(shù)組的長(zhǎng)度,返回創(chuàng)建好的int類型數(shù)組
int[] builderArray(int length);
}
/**
* 數(shù)組的構(gòu)造器引用
*/
public class Demo {
//定義一個(gè)方法,方法的參數(shù)傳遞創(chuàng)建數(shù)組的長(zhǎng)度和ArrayBuilder接口
//方法內(nèi)部根據(jù)傳遞的長(zhǎng)度使用ArrauBuilder中的方法創(chuàng)建數(shù)組并返回
public static int[] createArray(int length, ArrayBuilder ab){
return ab.builderArray(length);
}
public static void main(String[] args){
//調(diào)用createArray方法,傳遞數(shù)組的長(zhǎng)度和lambda表達(dá)式
int[] arr1 = createArray(10, (len)->{
//根據(jù)數(shù)組的長(zhǎng)度,創(chuàng)建數(shù)組并返回
return new int[len];
});
System.out.println(arr1.length);
/**
* 使用方法引用優(yōu)化lambda表達(dá)式
* 已知?jiǎng)?chuàng)建的就是int[]數(shù)組
* 數(shù)組的長(zhǎng)度也是已知的
* 就可以使用方法引用
* int[]引用new,根據(jù)參數(shù)傳遞的長(zhǎng)度來(lái)創(chuàng)建數(shù)組
*/
int[] arr2= createArray(10,int[]::new);
System.out.println(arr2.length);
}
}