一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第10天,点击查看活动详情
1 方法引用
- 在使用Lambda表达式的时候,我们实际上传递进去的代码就是一种解决方案:拿参数做操作
- 那么考虑一种情况: 如果我们在Lambda中所指定的操作方案,已经有地方存在相同方案,没有必要再写重复逻辑,如
usePrintable(s -> System.out.println(s));中System.out.println(s)就是重复逻辑 - 可以通过方法引用来使用已经存在的方案
1.1 方法引用符
-
方法引用符
::该符号为引用运算符,而它所在的表达式被称为方法引用
-
对比分析
- Lambda表达式:
usePrintable(s -> System.out.println(s));分析:拿到参数s之后通过Lambda表达式,传递给System.out.println()方法去处理 - 方法引用:
usePrintable(System.out:println);//隐含了把s参数给println方法分析:直接使用System.out中的println方法来取代Lambda,代码更加的简洁
- Lambda表达式:
-
推导与省略
- 如果使用Lambda,那么根据"可推导就是可省略”的原则,无需指定参数类型,也无需指定的重载形式,它们都将被自动推导
- 如果使用方法引用,也是同样可以根据上下文进行推导
- 方法引用是Lambda的李生兄弟(可以使用Lambda表达式就可以使用方法引用)
-
范例
package test;
public class Demo {
public static void main(String[] args) {
//Lambda表达式
usePrintable(i -> {
System.out.println(i); //888
});
//方法引用
usePrintable(System.out::println); //888
}
private static void usePrintable(Printable p) {
p.printInt(888);
}
}
1.2 引用类方法
-
常用方法引用
- 引用类方法
- 引用类的实例方法(成员方法)
- 引用对象的实例方法
- 引用构造器
-
引用类方法,其实就是引用类的静态方法
-
格式:
类名::静态方法 -
范例:
Integer::parselntInteger类的方法:public static int parseInt(String s)将此String转换为int类型数据 -
练习
-
接口类
package test;
public interface Converter {
int convert(String s);
}
- 测试类
package test;
public class Demo {
public static void main(String[] args) {
// useConverter(s -> {
// return Integer.parseInt(s);
// });
useConverter(s -> Integer.parseInt(s)); //666
//引用类方法
useConverter(Integer::parseInt); //666
//Lambda表达式被类方法替代时,他的形式参数全部传给静态方法做参数;如s字符串传递给parseInt方法
}
private static void useConverter(Converter c) {
int number = c.convert("666");
System.out.println(number);
}
}
1.3 引用类的实例方法(成员方法)
-
引用类的实例方法,其实就是引用类中的成员方法
-
格式:
类名::成员方法 -
练习
-
接口
package test;
public interface MyString {
String mySubString(String s,int x,int y);
}
- 测试类
package test;
public class Demo {
public static void main(String[] args) {
// useMyString((String s,int x,int y)->{
// return s.substring(x, y); //llo
// });
useMyString((s,x,y)-> s.substring(x, y)); // //llo
//引用类中的实例方法
useMyString(String::substring); //llo
//Lambda表达式中的形式参数(s,x,y)
//第一个参数作为调用者
//后面的参数全部传给实例方法作为参数
}
public static void useMyString(MyString m) {
String s = m.mySubString("HelloWorld", 2, 5);
System.out.println(s);
}
}
1.4 引用对象的实例方法(成员方法)
-
引用对象的实例方法,其实就引用类中的成员方法
-
格式:
对象名::成员方法 -
范例:
"HelloWorld"::toUpperCaseString类中的方法:public String toUpperCase()将此String所有字符转换为大写 -
练习
-
PrintString类
package test;
public class PrintString {
//把字符串转换成大写
public void printUpper(String s) {
String result = s.toUpperCase();
System.out.println(result);
}
}
- 接口
package test;
public interface Printer {
void printUpperCase(String s);
}
- 测试类
package test;
public class Demo {
public static void main(String[] args) {
// usePrinter((String s ) -> {
//// String result = s.toUpperCase();
//// System.out.println(result); //HELLO
// System.out.println(s.toUpperCase());
// });
usePrinter(s -> System.out.println(s.toUpperCase()));
//引用对象的实例方法
PrintString ps = new PrintString();
usePrinter(ps::printUpper); //HELLO
}
public static void usePrinter(Printer p) {
p.printUpperCase("hello");
}
}
1.5 引用构造器
-
引用构造器,就是引用构造方法
-
格式:
类名::new -
范例:
Student::new -
练习
-
测试类
package test;
public class Demo {
public static void main(String[] args) {
// useStudentBuilder((String name,int age) -> {
//// Student s =new Student(name,age);
//// return s;
// return new Student(name,age); //
// });
useStudentBuilder((name, age) -> new Student(name, age));
useStudentBuilder(Student::new); //小黑,10
//Lambda表达式被引用构造器代替时,他的形式参数全部传递给构造器作为参数
}
public static void useStudentBuilder(StudentBuilder sb) {
Student s = sb.build("小黑", 10);
System.out.println(s.getName() + "," + s.getAge());
}
}