JAVA 方法引用
体验方法引用
方法引用的出现原因:
在使用Lambda表达式的时候,我们实际上传递进去的代码就是一种解决方案:拿参数做操作
那么考虑一种情况:如果我们在Lambda中所指定的操作方案,已经有地方存在相同方案,那是否还有必要再写重复逻辑呢?答案肯定是没有必要
那我们又是如何使用已经存在的方案的呢?
这就是我们要讲解的方法引用,我们是通过方法引用来使用已经存在的方案 (其实就是使用一个现成的方法)
1 接口: 2 public interface Printable { 3 void printString(String s); 4 }
1 测试类: 2 public class PrintableDemo { 3 public static void main(String[] args) { 4 //Lambda表达式(简化) 5 usePrintable(s -> System.out.println(s)); 6 7 System.out.println("--------"); 8 9 //方法引用 10 usePrintable(System.out::println); 11 } 12 13 private static void usePrintable(Printable p) { 14 p.printString("爱生活,爱java"); 15 } 16 }
方法引用符
方法引用符:
:: 该符号为引用运算符,而它所在的表达式被称为方法引用
推导与省略:
- 如果使用Lambda,那么根据“可推导就是可省略”的原则,无需指定参数类型,也无需指定的重载形式,它们都将被自动推导
- 如果使用方法引用,也是同样可以根据上下文进行推导
- 方法引用是Lambda的孪生兄弟
引用类方法
引用类方法,其实就是引用类的静态方法
1 格式: 2 类名::静态方法 3 范例: 4 Integer::parseInt 5 Integer类的方法:public static int parseInt(String s) 将此String转换为int类型数据
使用说明:
Lambda表达式被类方法替代的时候,它的形式参数全部传递给静态方法作为参数
练习描述:
定义一个接口(Converter),里面定义一个抽象方法 int convert(String s);
定义一个测试类(ConverterDemo),在测试类中提供两个方法
一个方法是:useConverter(Converter c)
一个方法是主方法,在主方法中调用useConverter方法
1 接口: 2 public interface Converter { 3 int convert(String s); 4 }
1 测试类: 2 public class ConverterDemo { 3 public static void main(String[] args) { 4 //Lambda表达式: 5 useConverter(s -> Integer.parseInt(s)); 6 7 System.out.println("--------"); 8 9 //引用类方法: 10 //Lambda表达式被类方法替代的时候,它的形式参数全部传递给静态方法作为参数 11 useConverter(Integer::parseInt); 12 } 13 14 private static void useConverter(Converter c) { 15 System.out.println(c.convert("666")); 16 } 17 }
引用对象的实例方法
引用对象的实例方法,其实就引用类中的成员方法
1 格式: 2 对象::成员方法 3 范例: 4 "HelloWorld"::toUpperCase 5 String类中的方法:public String toUpperCase() 将此String所有字符转换为大写
使用说明:
Lambda表达式被对象的实例方法替代的时候,它的形式参数全部传递给该方法作为参数
练习描述:
定义一个类(PrintString),里面定义一个方法public void printUpper(String s):把字符串参数变成大写的数据,然后在控制台输出
定义一个接口(Printer),里面定义一个抽象方法void printUpperCase(String s)
定义一个测试类(PrinterDemo),在测试类中提供两个方法
一个方法是:usePrinter(Printer p)
一个方法是主方法,在主方法中调用usePrinter方法
1 接口: 2 public interface Printer { 3 void printUpperCase(String s); 4 }
1 具体类: 2 public class PrintString { 3 4 //定义一个方法public void printUpper(String s):把字符串参数变成大写的数据,然后在控制台输出 5 public void printUpper(String s){ 6 7 System.out.println(s.toUpperCase()); 8 } 9 }
1 测试类: 2 public class PrinterDemo { 3 public static void main(String[] args) { 4 //Lambda表达式 5 usePrinter(s -> System.out.println(s.toUpperCase())); 6 7 System.out.println("--------"); 8 9 //引用对象的实例方法 10 //Lambda表达式被对象的实例方法替代的时候,它的形式参数全部传递给该方法作为参数 11 //创建对象 12 PrintString ps=new PrintString(); 13 usePrinter(ps::printUpper); 14 } 15 16 private static void usePrinter(Printer p) { 17 p.printUpperCase("helloworld"); 18 } 19 }
引用类的实例方法
引用类的实例方法,其实就是引用类中的成员方法
1 格式: 2 类名::成员方法 3 范例: 4 String::substring 5 public String substring(int beginIndex,int endIndex) 6 从beginIndex开始到endIndex结束,截取字符串。返回一个子串,子串的长度为endIndex-beginIndex
使用说明:
Lambda表达式被类的实例方法替代的时候 第一个参数作为调用者 后面的参数全部传递给该方法作为参数
练习描述:
定义一个接口(MyString),里面定义一个抽象方法:String mySubString(String s,int x,int y);
定义一个测试类(MyStringDemo),在测试类中提供两个方法
一个方法是:useMyString(MyString my)
一个方法是主方法,在主方法中调用useMyString方法
1 接口: 2 public interface MyString { 3 String mySubString(String s,int x,int y); 4 }
1 测试类: 2 public class MyStringDemo { 3 public static void main(String[] args) { 4 //Lambda表达式 5 useMyString(((s, x, y) -> s.substring(x,y))); 6 7 //引用类的实例方法:Lambda表达式被类的实例方法替代的时候 第一个参数作为调用者 后面的参数全部传递给该方法作为参数 8 useMyString(String::substring); 9 } 10 11 private static void useMyString(MyString my) { 12 System.out.println(my.mySubString("HelloWorld",2,5)); 13 } 14 }
引用构造器
引用构造器,其实就是引用构造方法
1 格式 2 类名::new 3 范例 4 Student::new
使用说明:
Lambda表达式被构造器替代的时候,它的形式参数全部传递给构造器作为参数
练习描述:
定义一个类(Student),里面有两个成员变量(name,age)并提供无参构造方法和带参构造方法,以及成员变量对应的get和set方法
定义一个接口(StudentBuilder),里面定义一个抽象方法Student build(String name,int age);
定义一个测试类(StudentDemo),在测试类中提供两个方法
一个方法是:useStudentBuilder(StudentBuilder s)
一个方法是主方法,在主方法中调用useStudentBuilder方法
1 学生类: 2 public class Student { 3 4 private String name; 5 private int age; 6 7 public Student() { 8 } 9 10 public Student(String name, int age) { 11 this.name = name; 12 this.age = age; 13 } 14 15 public String getName() { 16 return name; 17 } 18 19 public void setName(String name) { 20 this.name = name; 21 } 22 23 public int getAge() { 24 return age; 25 } 26 27 public void setAge(int age) { 28 this.age = age; 29 } 30 }
1 接口: 2 public interface StudentBuilder { 3 Student build(String name,int age);// 接口的抽象方法在构造一个Student对象 4 }
1 测试类: 2 public class StudentDemo { 3 public static void main(String[] args) { 4 //Lambda表达式 5 useStudentBuilder(((name, age) ->new Student(name,age))); 6 7 System.out.println("--------"); 8 9 //引用构造器 10 useStudentBuilder(Student::new); // 调用Student类的构造方法 11 } 12 13 private static void useStudentBuilder(StudentBuilder sb) { 14 Student s = sb.build("令狐冲", 25); 15 System.out.println(s.getName()+s.getAge()); 16 } 17 }