时间 |
---|
4/21 |
方法引用
概念:
- 使用Lambda表达式,实际上传递进去的就是一种解决方案:拿参数做操作
- 方法引用 = 使用已经存在的方案
案例:
定义接口Printable,定义抽象方法 void printString(String s)
定义测试类PrinttableDemo,定义usePrintable(Printable p) 和 main方法调用usePrintable
package itiheima313.test1;
public class PrintableDemo {
public static void main(String[] args) {
// 使用Lambda表达式调用方法
usePrintable((String s)->{
System.out.println(s);
});
1 拿到参数s之后通过Lambda表达式,传递给System.out.println方法处理
// 方法引用 ::
usePrintable(System.out::println);
2 直接使用System.out中的println方法取代Lambda表达式。
// 可推导的就是可省略的。
// 方法引用 隐式的将参数传递给了方法 System.out 是对象 引用方法println
}
private static void usePrintable(Printable p){
p.printString("必须完成的事情,唯有靠自己才能完成");
// 也就是说 字符串就是参数传递给Printable接口中的printString方法。
}
}
public interface Printable {
void printString(String s);
}
方法引用符
:: 该符号为引用运算符,而它所在的表达式被称为方法引用。
推导与省略:
- 使用Lambda表达式,根据可推导就是可省略原则,无需指定参数类型和重载类型;
- 使用方法引用,同样可以根据上下文进行推导;
- 方法引用是Lambda的孪生兄弟。
Lambda表达式支持的方法引用
常见引用方式: 引用类的方法、引用对象的实例方法、引用类的实例方法、引用构造器。
引用方式 | 说明 | 参数传递问题 |
---|---|---|
引用类的方法 | 类名::静态方法 | Lambda表达式被对象的实例方法替代的时候,它的形式参数全部传递给该方法作为参数 Integer::parseInt |
引用对象的实例方法 | 对象名::成员方法 | Lambda表达式被对象的实例方法替代的时候,它的形式参数全部传递给该方法作为参数 对象::成员方法 “HelloWorld” ::toUpperCase |
引用类的实例方法 | 类名::成员方法 | Lambda表达式被类的实例方法替代的时候,第一个参数作为调用者,后面的参数全部传递给该方法作为参数 String::substring |
引用构造器 | 类名::new | Lambda表达式被构造器替代的时候,它的形式参数全部传递给该方法作为参数 类名::new |
引用类方法
引用类方法 = 引用类中的静态方法 类是java中自带的类
参数:Lambda表达式被引用类方法替代的时候,它的形式参数全部传递给静态方法作为参数。
格式:
类名::静态方法
案例:
// Integer::parseInt
Integer类的方法 public static int paresInt(String s) 将此String转换为int类型数据
* 类是java包中自带的类
练习:
接口(Converter),抽象方法int convert(String s)
测试类(ConverterDemo),两个方法:main 和 useConvert(Converter c)
package itiheima313.test2;
public class ConverterDemo {
public static void main(String[] args) {
1 Lambda表达式没有省略的形式
useConverter((String s) -> {return Integer.praseInt(s);})
2 Lambda表达式省略之后的形式
useConverter(s -> Integer.parseInt(s));
3 引用类方法的使用
useConverter(Integer::parseInt);
// Lambda表达式被引用类方法替代的时候,它的形式参数全部传递给静态方法作为参数。
}
private static void useConverter(Converter c){
int number = c.convert("666");
// Lambda表达式被引用类方法替代,字符串“666” 全部传递给静态方法作为参数。
System.out.println(number);
}
}
// 接口
public interface Converter {
int convert(String s);
}
引用对象的实例方法
引用对象的实例方法 = 引用类中的成员方法 对象.成员方法 对象所属的类是用户自己定义的;
参数:Lambda表达式被引用对象的实例方法替代的时候,它的形式参数全部传递给该方法作为参数。
格式:
对象::成员方法
案例:
“Helloworld”::toUpperCase
String类中的方法:public String toUpperCase() 将此String所有字符转换为大写
练习:
定义类(PrintString),定义方法public String toUpperCase(String s)
定义接口(Printer),抽象方法void printUpperCase(String s)
定义测试类(PrinterDemo),两个方法usePrinter(Printer P)、main方法调用usePrinter
package itiheima313.test3;
public class PrinterDemo {
public static void main(String[] args) {
// 在主方法中调用usePrinter方法,采用Lambda表达式
// usePrinter(s -> {
// String result = s.toUpperCase();
// System.out.println(result);
// });
// Lambda表达式省略格式
usePrinter(s -> System.out.println(s.toUpperCase()));
// 输出结果是 SUNSHINE
// 方法引用进行改进 对象::成员方法
PrintString ps = new PrintString();
usePrinter(ps::printUpper);
* Lambda 表达式 被对象的实例方法替代的时候,它的形式参数全部传递给该方法作为参数。
}
private static void usePrinter(Printer p){
p.printUpperCase("sunshine");
}
}
// 类 该类存在的原因是:接口的抽象方法的具体实现通过该类的方法实现了
public class PrintString {
public void printUpper(String s){
String result = s.toUpperCase();
System.out.println(result);
}
}
// 接口
public interface Printer {
void printUpperCase(String s);
}
引用类的实例方法
引用类的实例方法 = 引用类中的成员方法 类是java自带的类。
参数:Lambda表达式被引用类的实例方法替换,第一个参数作为调用者,其余参数全部传递入方法。
格式:
类名::成员方法
// 案例:
String::substring
String类中的方法:public String substring(int beginIndex,int endIndex)
从beginIndex开始到endIndex结束,截取字符串。返回一个子串,子串的长度是endIndex-beginIndex
练习:
接口(MyString),抽象方法:String mySubString(String s,int x,int y)
测试类(MyStringDemo),两个方法:useMyString(MyString my)和 main 调用useMyString方法。
package itiheima313.test4;
public class MyStringDemo {
public static void main(String[] args) {
// 使用Lambda表达式
useMyString((String s,int x,int y) -> {
return s.substring(x, y);
});
System.out.println("-----------");
// 省略
useMyString((s,x,y) -> s.substring(x,y));
System.out.println("-------------");
// 引用类的实例方法
useMyString(String::substring);
*Lambda表达式被类的实例方法替代的时候
*第一个参数作为调用者
*后面的参数全部传递给该方法作为参数
}
private static void useMyString(MyString my){
String s = my.mySubString("helloworld", 2, 5);
System.out.println(s);
// 输出结果是 llo
}
}
// 接口
public interface MyString {
String mySubString(String s,int x,int y);
}
引用构造器
引用构造器 = 引用构造方法
参数:Lambda表达式被引用构造器替代的时候,它的形式参数全部传递给构造器作为参数。
格式:
类名:: new
案例:
Student::new
练习:
类(Student),成员变量name、age;无参、带参构造方法;成员变量对应的get、set方法
接口(StudentBuilder),抽象方法Student build(String name,int age);
测试类(StudentDemo):方法 useStudentBuilder(StudentBuilder s),main方法调用useStudentBuilder方法
package itiheima313.test5;
public class StudentDemo {
public static void main(String[] args) {
// 匿名构造方法
useStudentBuilder(new StudentBuilder() {
@Override
public Student build(String name, int age) {
Student s = new Student(name, age);
return s;
}
});
// Lambda表达式 唯一的接口,且其中有唯一的抽象方法
useStudentBuilder((String name,int age) ->{
Student s = new Student(name, age);
return s;
});
// 省略版
useStudentBuilder((name,age) -> new Student(name,age));
// 引用构造器
useStudentBuilder(Student::new);
* Lambda 表达式被构造器替代的时候,它的形式参数全部传递给构造器作为参数
}
// 方法的参数是类名 则实际传递的是类的对象
private static void useStudentBuilder(StudentBuilder sb){
Student st = sb.build("汪苏泷", 30);
System.out.println(st.getName() + ", " + st.getAge());
}
}
public interface StudentBuilder {
Student build(String name,int age);
}
还有一个Student类 标准类