體驗方法引用 通過方法引用,來使用已經存在的方案。 定義一個介面,裡面有一個抽象方法: public interface Printable { void printString(String s); } 定義一個測試類: public class PrintDemo { public static ...
體驗方法引用
通過方法引用,來使用已經存在的方案。
- 定義一個介面,裡面有一個抽象方法:
public interface Printable {
void printString(String s);
}
- 定義一個測試類:
public class PrintDemo {
public static void main(String[] args) {
/*方式一
以Lambda表達式的方式,調用了介面的實現類,重寫了介面中的方法
介面作為參數,實際上參數是介面的實現類*/
usePrintable(s -> System.out.println(s));
/*方式二
方法引用符 ::
參數s:可推導的就是可省略的*/
usePrintable(System.out::println);
}
/**
* 一個以介面對象為形式參數的方法
* @param p 介面對象
*/
private static void usePrintable(Printable p) {
System.out.println("卡達世界盃");
}
}
- 運行結果:
卡達世界盃
卡達世界盃
方法引用符
:: 該符號為引用運算符,它所在的表達式被稱為方法引用
推導與省略
- Lambda表達式:根據“可推導就是可省略”原則,無需指定參數類型,也無需指定重載形式,他們都將被自動推導
- 方法引用:同樣可根據上下文推導
- Lambda表達式可以使用方法引用改進
- 定義一個介面,裡面有一個抽象方法
public interface Printable1 {
void printInt(int i);
}
- 定義測試類
public class PrintDemo1 {
public static void main(String[] args) {
usePrintable(i -> System.out.println(i));
usePrintable(System.out::println);
}
private static void usePrintable(Printable1 p) {
p.printInt(123);
}
}
- 運行結果
123
123
Lambda表達式支持的方法引用
常見的引用方式
- 引用類方法
- 引用對象的實例方法
- 引用類的實例方法
- 引用構造器
引用類方法
引用類方法,其實就是引用類的靜態方法
- 格式:類名::靜態方法
- 定義一個介面,裡面有一個抽象方法
public interface Convert {
int convert(String s);
}
- 定義一個測試類
public class ConvertDemo {
public static void main(String[] args) {
//Lambda
useConvert(s -> Integer.parseInt(s));
//引用類方法
//Lambda表達式被引用類方法替代時,它的形式參數全部傳遞給靜態方法作為參數
useConvert(Integer::parseInt);
}
private static void useConvert(Convert c) {
int i = c.convert("123");
System.out.println(i);
}
}
- 運行結果
123
123
引用對象的實例方法
引用對象的實例方法,其實就是引用類中的成員方法
- 格式:對象::成員方法
- 定義一個類,裡面有一個方法
public class PrintString {
/**
* 把字元串參數變成大寫,輸出到控制台
* @param s 字元串
*/
public void printUpper(String s){
System.out.println(s.toUpperCase());
}
}
- 定義一個介面,裡面有一個抽象方法
public interface Printer {
void printUpperCase(String s);
}
- 測試類
public class PrinterDemo {
public static void main(String[] args) {
//Lambda表達式
usePrinter(s -> System.out.println(s.toUpperCase()));
//引用對象的實例方法
//對象::成員方法
//Lambda表達式被對象的實例化替代時,它的形式參數全部傳遞給該方法作為參數
usePrinter(new PrintString()::printUpper);
}
private static void usePrinter(Printer p){
p.printUpperCase("How are you");
}
}
- 運行結果
HOW ARE YOU
HOW ARE YOU
引用類的實例方法
引用類的實例方法,其實就是引用類中的成員方法
格式:類名::成員方法
- 定義一個介面,裡面有一個抽象方法
public interface MyString {
String mySubString(String s, int x, int y);
}
- 定義一個測試類
public class MyStringDemo {
public static void main(String[] args) {
//Lambda表達式,截取字元串
useMyString((s, x, y) -> s.substring(x, y));
//引用類的實例方法
//第一個參數作為調用者
//後面的參數全部傳遞給該方法作為參數
useMyString(String::substring);
}
private static void useMyString(MyString m) {
System.out.println(m.mySubString("今天天氣很涼快", 2, 6));
}
}
- 運行結果
天氣很涼
天氣很涼
引用構造器
引用構造器,其實就是引用構造方法
- 格式:類名::new
- 定義一個學生類,裡面有兩個成員變數(name,age),並提供無參構造方法和帶參構造方法,以及成員變數的set和get方法
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
- 定義一個介面,裡面有一個抽象方法
public interface StudentBuilder {
Student build(String name,int age);
}
- 定義一個測試類
public class StudentDemo {
public static void main(String[] args) {
//Lambda表達式
useStudentBuilder((a, b) -> new Student(a, b));
//引用構造器
//Lambda表達式被構造器替代的時候,它的形式參數全部傳遞給構造器作為參數
useStudentBuilder(Student::new);
}
private static void useStudentBuilder(StudentBuilder s) {
Student stu = s.build("錢學森", 28);
System.out.println(stu.getName() + "-" + stu.getAge());
}
}
- 運行結果
``java
錢學森-28
錢學森-28