3.方法引用

1.体验方法引用

在Lambda中所指定的操作方案,已经有地方存在相同的方案时,可以通过方法引用来使用已经存在的方案。

代码:

  • 接口
package Study01;

public interface Printable {
    void printString(String s);
}
  • 测试类
package Study01;
/*
需求
- 定义一个接口(Printable):里面定义一个抽象方法:void printString(String s);
- 定义一个测试类(PrintableDemo),在测试类中提供两个方法
	- 一个方法是:usePrintable(Printable p);
	- 一个是主方法,在主方法中调用usePrintable方法
	*/
public class PrintableDemo {
    public static void main(String[] args) {
        //在主方法中调用usePrintable方法
//        usePrintable((String i)->{
//            System.out.println(i);
//        });

        usePrintable(i-> System.out.println(i));
//        System.out.println("CNMBJapan");

        //方法引用符:::
        usePrintable(System.out::println);
        //可推倒的就是可省略的
    }
    private static void usePrintable(Printable p){
        p.printString("CNMBJapan");
    }
}

2.方法引用符

方法引用符

  • :: 该符号为应用运算符,而它所在的表达式被称为方法引用。

在上节方法引用的代码中:

  • Lambda表达式: usePrintable(i-> System.out.println(i));
    • 分析:拿到参数s之后通过Lambda表达式,传递给System.out.println方法去处理。
  • 方法引用:usePrintable(System.out::println);
    • 分析:直接使用System.out中的println方法来取代Lambda,代码更加简洁。

推倒与省略:

  • 如果使用Lambda,那么根据“可推导就是可省略”的原则,无需指定参数类型,也无需指定重载形式,它们都将被自动推导。
  • 如果使用方法引用,也是同样可以根据上下文进行推导
  • 方法引用是Lambda的孪生兄弟

代码示例:

  • 接口
package Study02;

public interface Printable {
    void printString(int s);
}
  • 测试类
package Study02;
/*
需求
- 定义一个接口(Printable):里面定义一个抽象方法:void printString(int s);
- 定义一个测试类(PrintableDemo),在测试类中提供两个方法
	- 一个方法是:usePrintable(Printable p);
	- 一个是主方法,在主方法中调用usePrintable方法
	*/
public class PrintableDemo {
    public static void main(String[] args) {
        //在主方法中调用usePrintable方法
        usePrintable(i-> System.out.println(i));

        //方法引用
        usePrintable(System.out::println);
    }
    private static void usePrintable(Printable p){
        System.out.println(100);
    }
}

3. Lambda表达式支持的方法引用

常见的应用方法:

  • 引用类方法
  • 引用对象的实例方法
  • 引用类的实例方法
  • 引用构造器

1、引用类方法

引用类方法,其实就是引用类的静态方法

  • 格式:类名::静态方法

  • 范例:Integer::parseInt

    • Integer类的方法:public static int parseInt(String s)将此String转换为int类型数据。
  • 注:Lambda表达式被类方法替代的时候,它的形式参数全部传递给静态方法作为参数。

练习:

  • 接口
package Study03;

public interface Converter {
    int convert(String s);
}
  • 测试类
package Study03;
/*练习:
- 定义一个接口(`Converter`),里面定义一个抽象方法
	- `int convert(String s);`
- 定义一个测试类(`ConverterDemo`),在测试类中提供两个方法
	- 一个方法是:`useConverter(Converter C)`
	- 一个方法是主方法,在主方法中调用`useConverter`方法
*/
public class ConverterDemo {
    public static void main(String[] args) {
        //在主方法中调用`useConverter`方法
//        useConverter((String s)->{
//            return Integer.parseInt(s);
//        });

        useConverter(s->Integer.parseInt(s));

        //引用类方法改进
        useConverter(Integer::parseInt);
        //Lambda表达式被类方法替代的时候,它的形式参数全部传递给静态方法作为参数。

    }
    private static void useConverter(Converter c){
        int number = c.convert("111");
        System.out.println(number);
    }
}

2.引用对象的实例方法

引用对象的实例方法,其实就是引用类中的成员方法

  • 格式:对象::成员方法

  • 范例:"HelloWorld"::toUpperCase

    • String类中的方法:public String toUpperCase():将此String所有字符转换为大写。
  • 注:Lambda表达式被对象的实例方法代替的时候,它的形式参数全部传递给该方法作为参数

练习:

  • 接口
package Study04;

public interface Printer {
    void printUpperCase(String s);
}
  • PrintString
package Study04;

public class PrintString {
    // 把字符串参数变成大写的数据,然后在控制台输出。
    public  void printUpper(String s){
        String result = s.toUpperCase();
        System.out.println(result);
    }
}
  • 测试类
package Study04;
/*练习:
- 定义一个类(PrintString),里面定义一个方法
	- public void printUpper(String s):把字符串参数变成大写的数据,然后在控制台输出。
- 定义一个接口(Printer),里面定义一个抽象方法
	- void printUpperCase(String s);
- 定义一个测试类(PrinterDemo),在测试类中提供两个方法
	- 一个方法是:usePrinter(Printer p)
	- 一个方法是主方法,在主方法中调用usePrinter方法
*/
public class PrinterDemo {
    public static void main(String[] args) {
        //在主方法中调用usePrinter方法
//        usePrinter((String s)->{
//            String s1 = s.toUpperCase();
//            System.out.println(s1);
//        });

        usePrinter(s-> System.out.println(s.toUpperCase()));

        //引用对象的实例方法
        PrintString ps = new PrintString();
        usePrinter(ps::printUpper);
        //Lambda表达式被对象的实例方法代替的时候,它的形式参数全部传递给该方法作为参数
    }
    private static void usePrinter(Printer p){
        p.printUpperCase("HelloWorld");
    }
}

3.引用类的实例方法

引用类的实例方法,其实就是引用类中的成员方法

  • 格式:类名::成员方法

  • 范例:String::substring

    • String类中的方法:public String substring(int beginIndex,int endIndex)
      beginIndex开始到endIndex结束,截取字符串。返回一个子串,子串的长度为endIndex-beginIndex
  • 注:

    • Lambda表达式被类的实例方法替代的时
    • 第一个参数作为调用者
    • 后面的参数全部传递给该方法作为参数。

练习:

  • 接口
package Study05;

public interface MyString {
    String mySubString(String s,int x,int y);
}

  • 测试类
package Study05;
/*练习:
- 定义一个接口(MyString),里面定义一个抽象方法
	- String mySubString(String s,int x,int y);
- 定义一个测试类(MyStringDemo),在测试类中提供两个方法
	- 一个方法是:useMyString(MyString my)
	- 一个方法是主方法,在主方法中调用useMyString方法
	*/
public class MyStringDemo {
    public static void main(String[] args) {
        //在主方法中调用useMyString方法
//        useMyString((String s,int x,int y)->{
//            return s.substring(x,y);
//        });
        useMyString((s,x,y)->s.substring(x,y));

        //引用类的实例方法
        useMyString(String::substring);
        //Lambda表达式被类的实例方法替代的时候
        //第一个参数作为调用者
        //后面的参数全部传递给该方法作为参数。
    }
    private static void useMyString(MyString my){
        String result = my.mySubString("HelloWorld", 1, 5);
        System.out.println(result);
    }
}

4.引用构造器

引用构造器

  • 格式:类名::new

  • 范例:Student::new

  • 注:Lambda表达式被构造器代替的时候,它的形式参数全部传递给构造器作为参数。

练习:

  • 接口
package Study06;
/*- 定义一个接口(StudentBuilder),里面定义一个抽象方法
	- Student build(String name,int age);*/
public interface StudentBuilder {
    Student build(String name,int age);
}
  • Student
package Study06;
/*
- 定义一个类(Student),里面有两个成员变量(name,age)
- 提供无参构造方法和带参构造方法,以及成员变量对应的get和set方法
	*/
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;
    }
}
  • 测试类
package Study06;
/*
- 定义一个类(Student),里面有两个成员变量(name,age)
	- 提供无参构造方法和带参构造方法,以及成员变量对应的get和set方法
- 定义一个接口(StudentBuilder),里面定义一个抽象方法
	- Student build(String name,int age);
- 定义一个测试类(StudentDemo),在测试类中提供两个方法
	- 一个方法是:useStudentBuilder(StudentBuilder s)
	- 一个方法是主方法,在主方法中调用useStudentBuilder方法
	*/
public class StudentDemo {
    public static void main(String[] args) {
        //在主方法中调用useStudentBuilder方法
//        useStudentBuilder((String name,int age)->{
//            return new Student(name,age);
//        });
        useStudentBuilder(((name, age) -> new Student(name,age)));

        //引用构造器
        useStudentBuilder(Student::new);
        //Lambda表达式被构造器代替的时候,它的形式参数全部传递给构造器作为参数。
    }
    private static void useStudentBuilder(StudentBuilder s){
        Student student = s.build("迪丽热巴", 18);
        System.out.println(student.getName()+","+student.getAge());
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幺洞两肆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值