Java学习之方法引用

一、方法引用

1. 作用
  • 通过直接引用方法名的方式来重写函数式接口中的抽象方法
2. 使用前提
  • 如果Lambda要表达的函数方案已经存在于某个方法的实现中,那么可以通过双冒号来引用该方法作为Lambda的替代者
  • 双冒号"::"为引用运算符
3. 注意事项
  • Lambda中传递的参数,一定是方法引用中的那个方法可以接收的数据类型,否则就会抛出异常

二、通过对象名来引用成员方法

1. 使用前提
  • 对象名是已经存在的
  • 成员方法是已经存在的
2. 代码格式
对象名::成员方法名
3. 代码演示
  • 定义函数式接口
@FunctionalInterface
public interface Printable {
    void print(String s);
}
  • 定义对象和成员方法
/**
 * 使字符串大写并打印
 * */
public class MethodRerObject {
    public void printUpperCaseString(String str){
        System.out.println(str.toUpperCase());
    }
}
  • 通过对象名引用成员方法
public class DemoObjectMethodReference {
    // 静态方法:实现接口中的抽象方法
    public static void printString(Printable p){
        p.print("hello world");
    }

    public static void main(String[] args) {
        MethodRerObject obj = new MethodRerObject();

        // Lambda方式:通过Lambda表达式重写抽象方法的方法体,即调用成员方法
        printString((s)->{
            obj.printUpperCaseString(s);
        });

        // 优化方式:通过对象名引用成员方法
        printString(obj::printUpperCaseString);
    }
}

三、通过类名引用静态成员方法

1. 使用前提
  • 类已经存在
  • 静态成员方法已经存在
2. 代码格式
类名::静态方法名
3. 代码演示
  • 定义函数式接口
@FunctionalInterface
public interface Calcable {
    // 定义一个抽象方法,传递一个整数,对整数进行绝对值计算并返回
    int calAbs(int number);
}
  • 通过类名引用静态成员方法
public class DemoStaticMethodReference {
    // 定义一个方法,方法的参数是要计算的绝对值整数和函数式接口
    public static int method(int number, Calcable c){
        return c.calAbs(number);
    }

    public static void main(String[] args) {
        // Lambda方式:通过传递lambda表达式重写抽象方法的方法体,返回计算后的结果
        int number = method(-10, (n)->{
           return Math.abs(n);
        });
        System.out.println(number);

        /**
         * 通过方法引用优化Lambda表达式
            * Math是类名
            * abs()方法为静态成员方法
         * */
        int number2 = method(-10, Math::abs);
        System.out.println(number2);
    }
}

四、通过super引用成员方法

1. 代码格式
super::成员方法名
2. 代码演示
  • 定义函数式接口
@FunctionalInterface
public interface Greetable {
    void Greet();
}
  • 定义父类
/**
 * 定义父类
 * */
public class Human {
    public void sayHello() {
        System.out.println("你好,我是Human");
    }
}
  • 定义子类,并通过方法引用调用父类的成员方法
/**
 * 定义子类,并通过方法引用调用父类的成员方法
 * */
public class Man extends Human{
    // 重写父类方法
    @Override
    public void sayHello() {
        System.out.println("你好,我是man");
    }

    // 定义一个方法传递Greetable接口
    public void method(Greetable g){
        g.greet();
    }

    public void show(){
    
        // Lambda方式:调用method方法,方法的参数是函数式接口
        method(()->{
            // 调用父类的sayHello方法
            super.sayHello();
        });

       // 方法引用:由于存在子父类的关系,所以可以直接通过super引用方法
        method(super::sayHello);
    }

    public static void main(String[] args) {
        new Man().show();
    }
}

五、通过this引用本类的成员方法

1. 代码格式
this::成员方法名
2. 代码演示
  • 定义函数式接口
@FunctionalInterface
public interface Greetable {
    void Greet();
}
  • 定义一个类,使用this引用本类中的方法
public class Man{
    // 定义一个成员方法
    public void sayHello() {
        System.out.println("你好,我是man");
    }

    // 定义一个方法传递Greetable接口
    public void method(Greetable g){
        g.greet();
    }

    public void show(){

        // Lambda方式:调用method方法,方法的参数是函数式接口
        method(()->{
            // 调用本类中的sayHello方法
            this.sayHello();
        });
		
		// 方法引用
        method(this::sayHello);
    }

    public static void main(String[] args) {
        new Man().show();
    }
}

六、类的构造方法引用

1. 作用
  • 使用方法引用来创建对象
2. 代码格式
类名::new
3. 代码演示
  • 定义一个类,并创建构造方法
public class Person {
    private String name;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
  • 定义函数式接口,可以根据传递的姓名,创建对象
@FunctionalInterface
public interface PersonBuilder {
    // 定义一个方法,根据传递的姓名,创建对象
    Person builderPerson(String name);
}
  • 定义一个类,分别通过Lambda方式和方法引用方式创建对象
public class Demo {
    // 定义一个方法,参数传递"姓名"和 "PersonBuilder接口",方法中通过姓名来创建Person对象
    public static void printPersonName(String name, PersonBuilder p) {
        Person person = p.builderPerson(name);
        System.out.println(person.getName()); 
    }

    public static void main(String[] args) {
        // Lambda方式:根据传递的姓名来构造Person对象
        printPersonName("古力娜扎", (name)->{
            return new Person(name);
        });

        // 方法引用
        printPersonName("迪丽热巴",Person::new);
    }
}

七、数组的构造器引用

1. 作用
  • 使用方法引用来创建数组
2. 代码格式
int[]::new
3. 代码演示
  • 定义一个创建数组的函数式接口
/**
 * 定义一个创建数组的函数式接口
 * */
@FunctionalInterface
public interface ArrayBuilder {
    // 定义一个创建int类型数组的方法,参数传递数组的长度,最后返回创建好的int类型的数组
    int[] builderArray(int length);
}
  • 定义一个类,分别通过lambda方式和方法引用来创建数组
public class Demo {
    /**
     * 定义一个方法
     * 方法的参数传递创建数组的长度和ArrayBuilder接口
     * 方法内部根据传递的长度使用ArrayBuilder中的方法并返回创建后的数组
     * */
    public static int[] createArray(int length, ArrayBuilder ab) {
        return ab.builderArray(length);
    }

    public static void main(String[] args) {

        // 使用Lambda方式传参创建数组
        int[] array1 = createArray(10, (length)->{
            return new int[length];
        });
        System.out.println(array1.length);

        // 使用方法引用创建数组
        int[] array2 = createArray(11, int[]::new);
        System.out.println(array2.length);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值