public class Demo1Print {
/*方法參數傳遞Printable接口,對字元串列印輸出
* */
public static void printString(Printable p) {
p.print("I Love Java");
}
public static void main(String[] args) {
printString(s->System.out.println(s));
/*分析;Lambda表達式的目的,列印參數傳遞的字元串
* 把s傳給了System.out對象,調用out中的方法pritnln(),對字元串進行輸出
* 注意:
* 此時的 System.out對象是存在的,println()方法也是存在的
* 我們可以使用方法引用來優化Lambda表達式,使用System.out對象直接調用println()方法
* 格式: 對象::方法
* 雙冒号為 引用運算符,它所在的表達式被稱為方法引用
* */
printString(System.out::println);
}
}
😀2、通過對象名 引用成員方法
使用前提:對象名 和 成員方法 已經存在 才可以使用 對象名 來引用 成員方法
注意:如果類中的方法是靜态的 就無法使用對象調用 直接用類名 引用 靜态成員方法
練習
public class Demo2_ObjectMethodReference {
public static void printString(Printable p) {
p.print("java");
}
public static void main(String[] args) {
//調用printString方法,方法的參數Printable是一個函數式接口,是以可以傳遞Lambda表達式
printString((s)->{
//建立MethodFer對象
MethodFer mf = new MethodFer();
//使用MethodFer建立的對象 調用 該類中的方法printUpperCase
mf.printUpperCase(s); //輸出JAVA
});
//方法引用(優化)
MethodFer mf2 = new MethodFer();
printString(mf2::printUpperCase); //輸出JAVA
//或者
printString(new MethodFer()::printUpperCase); //輸出JAVA
/*
* printString(MethodFer::printUpperCase);
* Cannot make a static reference to the non-static method
* printUpperCase(String) from the type MethodFer
*/
//通過類 引用 靜态成員方法
printString(MethodFer::printLowerCase); //輸出java
}
}
class MethodFer{
public void printUpperCase(String str) {
System.out.println(str.toUpperCase());
}
public static void printLowerCase(String str) {
System.out.println(str.toLowerCase());
}
}
😀3、通過類名引用靜态成員方法
比如:類Math 中的abs方法是靜态方法
前提:
類已經存在,靜态成員方法也存在, 就可以直接通過類型引用靜态成員方法
測試
public class Demo3_StaticMethodReference {
public static int calcator(int num,Calc c) {
return c.calcABS(num);
}
public static void main(String[] args) {
int num = calcator(-10,n->Math.abs(n));
System.out.println(num);
/*使用方法引用來優化Lambda表達式
* Math類是存在的 abs方法也是存在的
* */
int num2 = calcator(-20,Math::abs);
System.out.println(num2);
}
}
@FunctionalInterface
interface Calc{
public abstract int calcABS(int num);
}
😀4、通過super 引用父類的成員方法,通過this 引用本類的成員方法
public class Demo4_Super_this_MethodReference {
public static void main(String[] args) {
Man man = new Man();
man.show1();
man.show2();
}
}
//定義一個父類
class Human{
//定義sayHello方法
public void Say() {
System.out.println("Say Hello! I am Father");
}
}
//定義一個子類
class Man extends Human{
//重寫父類sayHello方法
public void Say() {
System.out.println("Say Hi! I am son");
}
//定義一個方法 參數傳遞Greetable接口
public void method(Greetable g) {
g.greet();
}
//
public void show1() {
//調用method方法,方法的參數Greetable是一個函數式接口,是以可以傳遞Lambda表達式
// method(()->{
// //建立父類對象
// Human h = new Human();
// //調用父類的sayHello方法
// h.Say();
// });
//因為有子父類關系 是以存在關鍵字super 代表父類 可以直接使用super調用父類的方法
// method(()->{
// super.Say();
// });
/*繼續優化 既然 可以直接使用super調用父類的方法
* 那麼就可以使用super引用類的成員方法
* 因為super是已經存在的 Say方法是已經存在的
* 是以可以直接使用super引用父類的Say方法
*/ method(super::Say);
}
public void show2() {
//調用method方法,方法的參數Greetable是一個函數式接口,是以可以傳遞Lambda表達式
// method(()->{
// //建立本類對象
// Man man = new Man();
// //通過本類對象 調用本類的成員方法
// man.Say();
// });
//關鍵字this 代表本類 可以直接使用this調用本類的方法
// method(()->{
// this.Say();
// });
//繼續優化 使用this 引用本類方法
method(this::Say);
}
}
//定義一個見面的函數式接口
@FunctionalInterface
interface Greetable{
public abstract void greet();
}
😀5、通過構造器 引用成員方法
public class Demo5_ConstructorMethodReference {
//定義一個方法 參數傳遞 姓名 和create接口
public static Person getName(String n,Create c) {
return c.create(n);
}
public static void main(String[] args) {
//調用getName方法
// Person name = getName("神廚小福貴",(s)->{
// return new Person(s);
// });
// System.out.println(name);
/*使用方法引用優化Lambda表達式
* 構造方法 new Person(String name); 已知
* 建立對象 new 已知
* 就可以使用Person 引用new 建立對象
* */
Person name = getName("比卡丘",Person::new);
System.out.println(name);
}
}
//定義一個函數式接口
@FunctionalInterface
interface Create{
//方法傳回值為Person 因為要傳回建立的對象
public abstract Person create(String name);
}
//定義一個類
class Person{
private String name;
public Person(String name) {
super();
this.name = name;
}
public Person() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person [name=" + name + "]";
}
}
public class SupplierDemo1 {
//定義一個方法,方法的參數傳遞Supplier<T>接口,泛型執行String,get方法就會傳回一個String
public static String getString(Supplier<String> sup) {
return sup.get();
}
public static void main(String[] args) {
System.out.println(getString( ()->{ return "光頭強";}));
System.out.println(getString( ()-> "天才威"));
}
}
題目:求數組元素的最大值:
使用Supplier接口作為方法參數類型,通過Lambda表達式求出int數組的最大值
public class SupplierDemo_GetArrMax {
public static int getMax(Supplier<Integer> sup) {
return sup.get();
}
public static void main(String[] args) {
//定義一個整型數組
int[] arr = {1,8,5,9,2,55,11,77,66};
//調用getMax方法,使用Supplier接口作為方法參數類型
//通過Lambda表達式求出int數組的最大值
int maxNum = getMax( ()->{
//定義一個變量存放數組中第一個數
int num = arr[0];
//循環查找
for (int i : arr) {
if(i>num)
num = i;
}
return num;
});
System.out.println("數組中最大值為:"+maxNum);
}
}