1. 方法引用
1.1 Lambda冗餘問題以及方法引用初識
package com.qfedu.d_methodreference;
/**
* 函數式接口
*
* @author Anonymous
*/
@FunctionalInterface
interface PrintMethod {
void print(String str);
}
/**
* Lambda冗餘問題
*
* @author Anonymous 2020/3/12 15:53
*/
public class Demo1 {
public static void main(String[] args) {
/*
使用Lambda表達式來展示字符串
IDEA有一個提示,這裏可以繼續優化
目標:
testPrint方法,需要將String str交給 PrintMethod進行處理
PrintMethod處理的方式是System.out.println
PrintMethod是一個函數式接口,可以使用Lambda表達式完成代碼
但是貌似和這個接口,這裏Lambda不夠接近目標
明確:
1. 我要用System.out對象
2. 需要使用println方法
3. 需要處理的數據是明確的
*/
testPrint("鄭州加油!!!", str -> System.out.println(str));
// 利用方法引用來處理當前代碼
/*
調用對象:
System.out
執行方法:
println方法
需要處理的數據(可推導,可省略)
"中國加油!!!祖國萬歲!!!"
::
Java中【方法引用】使用的運算符,標記
*/
testPrint("中國加油!!!祖國萬歲!!!", System.out::println);
}
/**
* 該方法是一個使用函數式接口作爲方法參數的一個方法
*
* @param str String類型的字符串
* @param pm PrintMethod函數式接口
*/
public static void testPrint(String str, PrintMethod pm) {
pm.print(str);
}
}
1.2 方法引用小要求
testPrint("鄭州加油!!!", str -> System.out.println(str));
testPrint("鄭州加油!!!", System.out::println);
1. 明確對象
對象 ==> 調用者
類對象,類名,super,this,構造方法,數組構造方法
2. 明確的執行方法
該方法只有名字不需要顯式出現參數
3. 需要處理的數據
【聯想,推導,省略】
4. :: 方法引用格式
1.3 通過類對象來執行方法引用
1. 明確對象
類對象
2. 明確執行的方法
自定義
3. 處理的數據
簡單要求爲String類型
package com.qfedu.e_objectmethodreference;
/**
* 函數式接口
* 明確約束方法
* 方法類型是
* 參數是String類型參數
* 沒有返回值
*/
@FunctionalInterface
public interface Printable {
void method(String str);
}
/**
* 自定義類
*/
public class ObjectMethodReference {
/**
* ObjectMethodReference類內的【成員方法】
* 1. 參數是String類型
* 2. 沒有返回值
* @param str 參數
*/
public void print(String str) {
System.out.println(str.toLowerCase());
}
/**
* ObjectMethodReference類內的【成員方法】
* 1. 參數是String類型
* 2. 沒有返回值
* @param str 參數
*/
public void printSubstring(String str) {
System.out.println(str.substring(3));
}
public void saolei() {
System.out.println("無參數方法");
}
}
```
```java
package com.qfedu.e_objectmethodreference;
/**
* 類對象使用方法引用展示
*
* @author Anonymous 2020/3/12 16:18
*/
public class Demo2 {
public static void main(String[] args) {
/*
test方法需要使用一個Printable接口,執行對應的print方法
這裏需要引用ObjectMethodReference類對象對應的print方法,該方法有展示能力
*/
ObjectMethodReference obj = new ObjectMethodReference();
/*
執行的對象:
ObjectMethodReference的類對象
明確執行的方法:
print方法
執行的目標:
"ABCDE" 可省略,可推導
*/
test(obj::printSubstring);
}
/**
*
* @param printable 函數式接口,約束的是方法類型
*/
public static void test(Printable printable) {
printable.method("ABCDE");
}
}
```
1.4 通過類名來執行方法引用
package com.qfedu.f_classmethodreference;
import java.util.List;
/**
* 函數式接口
*/
@FunctionalInterface
public interface PrintList {
/**
* 方法參數爲List集合
* 沒有返回值
* @param list List集合
*/
void print(List<?> list);
}
package com.qfedu.f_classmethodreference;
import java.util.List;
/**
* 通過列明調用的靜態方法,演示類
*/
public class ClassMethodReference {
/**
* 該方法符合要求
* 沒有返回值
* @param list list集合
*/
public static void showListInfo(List<?> list) {
for (Object o : list) {
System.out.println(o);
}
}
}
package com.qfedu.f_classmethodreference;
import java.util.ArrayList;
/**
* 通過類名來執行方法引用
*
* @author Anonymous 2020/3/12 16:39
*/
public class Demo3 {
public static void main(String[] args) {
/*
明確調用對象
當前方法是一個靜態成員方法,需要通過類名調用
明確調用方法
showListInfo
明確的數據
ArrayList<String> list = new ArrayList<>();
可省略,可推導
*/
testClass(ClassMethodReference::showListInfo);
/*
Lambda表達式
*/
testClass(list -> {
for (Object o : list) {
System.out.println(o);
}
});
}
/**
* 利用了一個函數式接口作爲方法的參數
*
* @param printList 函數式接口
*/
public static void testClass(PrintList printList) {
ArrayList<String> list = new ArrayList<>();
list.add("BMW");
list.add("Audi");
printList.print(list);
}
}
1.5 通過super關鍵字執行方法引用
package com.qfedu.g_supermethodreference;
/**
* @author Anonymous 2020/3/12 16:52
*/
public interface SaySomeThing {
void say();
}
package com.qfedu.g_supermethodreference;
/**
* @author Anonymous 2020/3/12 16:53
*/
public class Father {
public void sayHello() {
System.out.println("你好 Java");
}
}
package com.qfedu.g_supermethodreference;
import java.util.Scanner;
/**
* @author Anonymous 2020/3/12 16:53
*/
public class Son extends Father {
public static void main(String[] args) {
//lambda
testSay(() -> System.out.println("你好"));
new Son().sonMethod();
}
/**
* 這裏的參數是一個函數式接口,這裏需要提供給一個符合要求的方法
* @param sst 函數式接口參數
*/
public static void testSay(SaySomeThing sst) {
sst.say();
}
public void sonMethod() {
/*
父類中有一個無參數無返回值的sayHello
滿足當前SaySomeThing函數式接口,方法要求
執行的對象
super關鍵字,因爲該方法在父類內
執行的方法:
sayHello
無需參數
*/
testSay(super::sayHello);
}
}
1.6 通過this關鍵字執行方法引用
package com.qfedu.h_thismethodreference;
/**
* @author Anonymous 2020/3/12 17:00
*/
public interface ORM {
/**
* int ==> String
* @param i int類型
* @return String類型
*/
String toStringType(int i);
}
package com.qfedu.h_thismethodreference;
/**
* @author Anonymous 2020/3/12 17:01
*/
public class ThisDemo {
public void test() {
String s = testThis(i -> i + ":");
System.out.println(s);
/*
調用方法的對象
this
執行的方法:
turn方法
處理的數據
10 (可省略,可聯想)
*/
String s1 = testThis(this::turn);
}
public String turn(int i) {
return i + ":字符串";
}
public static String testThis(ORM orm) {
return orm.toStringType(10);
}
public static void main(String[] args) {
new ThisDemo().test();
}
}
1.7 類構造方法引用
package com.qfedu.a_methodreference;
/**
* 函數式接口
*
* @author Anonymous 2020/3/13 9:56
*/
public interface PersonMethodReference {
/**
* 該方法是獲取Person類對象,形式參數是Stringname
* @param name String類型
* @return Person類對象
*/
Person getPerosnObject(String name);
}
package com.qfedu.a_methodreference;
/**
* Perosn類
*
* @author Anonymous 2020/3/13 9:56
*/
public class Person {
private String name;
public Person() {}
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
package com.qfedu.a_methodreference;
/**
* 方法引用構造方法演示
*
* @author Anonymous 2020/3/13 9:54
*/
public class Demo1 {
public static void main(String[] args) {
/*
這裏使用利用Lambda表達式完成對象創建
這裏可以使用方法引用完成,引用的方法是Person類的構造方法
*/
printPerson("騷磊", name -> new Person(name));
/*
Person::new
Person是數據類型,是類名
new 引用的關鍵字(方法)
new --> 對應參數的構造方法
*/
printPerson("航海中路彭于晏", Person::new);
}
/**
* 方法參數使用到一個函數式接口的引用,這裏可以是引用Lambda表達式來完成
*
* @param name String類型
* @param method 函數式接口
*/
public static void printPerson(String name, PersonMethodReference method) {
System.out.println(method.getPerosnObject(name));
}
}
1.8 數組創建方式引用
package com.qfedu.b_arrayConstructor;
/**
* 函數式結構
*
* @author Anonymous 2020/3/13 10:07
*/
@FunctionalInterface
public interface ArrayConstructorReference {
/**
* 限制指定容量,返回int類型數組
* @param capacity 要求數組的初始化容量
* @return 返回一個int類型數組
*/
public int[] createIntArray(int capacity);
}
package com.qfedu.b_arrayConstructor;
/**
* 演示數組構造方式方法引用
*
* @author Anonymous 2020/3/13 10:08
*/
public class Demo1 {
public static void main(String[] args) {
/*
利用Lambda表達式完成函數式接口使用,創建數組對象
*/
int[] intArray = getIntArray(10, capacity -> new int[capacity]);
System.out.println(intArray);
/*
數組構造方法方法引用
明確數據類型
int 類型數組
[] 數組標記
:: new 需要申請空間,創建對應的數組
*/
int[] intArray1 = getIntArray(20, int[]::new);
System.out.println(intArray1);
}
/**
* 這裏是創建Int類型數組返回的方法
*
* @param capacity 指定的數組容量
* @param ref 函數式接口
* @return 指定容量的int類型數組
*/
public static int[] getIntArray(int capacity, ArrayConstructorReference ref) {
return ref.createIntArray(capacity);
}
}