方法引用

方法引用符

  • :: 该符号为引用运算符,而它所在的表达式被称为方法引用
    方法引用中的代码
  • Lambda 表达式:usePrintable(s - > System.out.println(s));
    分析:拿到参数s之后通过Lambda表达式,传递给System.out.println方法处理
  • 方法引用:usePrintable(System.out::println);
    分析:直接使用System.out中的println方法来取代Lambda,代码更加的简洁
    推导与省略
  • 如果使用Lambda,那么根据“可推导就是可省略”的原则,无需指定参数类型,也无参指定的重载形式,它们都将被自动推导
  • 如果使用方法引用,也是可以根据上下文进行推导
  • 方法引用是Lambda的孪生兄弟
接口
public interface Printable {
    void  printInt(int i);
}
测试类
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) {
        p.printInt(666);
    }
}

Lambda表达式支持的方法引用

常见的引用方式

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

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

  • 格式: 类名::静态方法
  • 范例: Integer::parselnt
    Integer类的方法:public static int parselnt(String s)将此String 转换为int类型数据
    练习:
  • 定义一个接口(Converter),里面定义一个抽象方法
    int convert (String s);
  • 定义一个测试类(ConvertDemo),在测试类中提供两个方法
    一个方法是:useConverter(Converter c)
    一个方法是主方法,在主方法中调用useConverter方法
接口
public interface Converter {
    int convert (String s);
}
测试类
public class ConvertDemo {
    public static void main(String[] args) {
        useConverter( s -> Integer.parseInt(s));
        // 引用类方法
        useConverter(Integer::parseInt);
        // Lambda表达式被类方法替代的时候,它的形式参数全部传递给静态方法作为参数
    }
    private static void useConverter(Converter c){
        int i = c.convert("999");
        System.out.println(i);
    }
}

引用对象的实例方法

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

  • 格式: 对象::成员方法
  • 范例: "HelloWorld"::toUpperCase
    String 类中的方法:public String toUpperCase()将此String 所有字符转换为大写
接口
public interface Printer {
    void printUpperCase(String s);
}
被引用类
public class PrintString {
    public void  printUpper(String s) {
        String result = s.toUpperCase();
        System.out.println(result);
    }
}
测试类
public class PrinterDemo {
    public static void main(String[] args) {
        usePrinter(s -> {
//            String reuslt = s.toUpperCase();
//            System.out.println(reuslt);
            System.out.println(s.toUpperCase());

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

    }
    private static void usePrinter(Printer p) {
        p.printUpperCase("HelloWorld");
    }
}

引用类的实例方法

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

  • 格式: 类名:: 成员方法
  • 范例: 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)
    一个方法是主方法,在主方法中调用useMyString方法
接口
public interface MyString {
    String mySubString(String  s,int x,int y);
}
测试类
public class MyStringDemo {
    public static void main(String[] args) {
        useMyString( (s,x,y)-> s.substring(x, y));
        //引用类的实例方法’
        useMyString(String::substring);
        //Lambda表达式被类的实例方法替代的时候:
        // 第一个参数作为调用者
        // 后面的参数全部传递给该方法作为参数

    }

    private static void useMyString(MyString my) {
        String s = my.mySubString("tim", 0, 2);
        System.out.println(s);
    }
}

引用构造器

引用构造器,其实就是引用构造方法

  • 格式: 类名::new
  • 范例: Student::new
    练习:
  • 定义一个类(Student),里面有两个成员变量(name,age)
    并提供无参构造方法和带参构造方法,以及成员变量对应的get和set方法
  • 定义一个接口(StudentBuilder),里面定义一个抽象方法
    Student build (String name, int age);
  • 定义一个测试类(StudentDemo),在测试类中提供两个方法
    一个方法是:useStudentBuilder(StudentBuilder s)
    一个方法是主方法,在主方法中调用useStudentBuilder方法
接口
public interface StudentBuilder {
    Student build (String name, int age);
}
学生类
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 class StudentDemo {
    public static void main(String[] args) {
       useStudentBuilder((name,age) -> {
           Student s = new Student(name,age);
          return s;
       });
       // 引用构造器
       useStudentBuilder(Student::new);
       // Lambda表达式被构造器替代的时候,它的形式参数全部传递给构造器作为参数
    }

    private static void useStudentBuilder(StudentBuilder sb) {
        Student s = sb.build("林青霞", 30);
        System.out.println(s.getName() + "," + s.getAge());
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容