java-方法引用

/**
 * 方法引用格式:
 *  双冒号::  引用运算符,它所在的表达式被称为方法引用。如果Lambda表达式
 *  的函数方案已经存在于某个地方的实现中,
 *  ===》那么可以通过双冒号来引用改方法作为Lambda表达式的代替者
 */

例子:

public class Demo01Print {
    private static void printString(Printable p){
      p.print("quan");
    }

    public static void main(String[] args) {
        printString((s)->{
            System.out.println(s);
        });
        /**
         * 表达式的目的:打印参数传递的字符串
         * 把参数s,传递给System.out对象,调用out对象的pringln方法进行输出
         *          System.out对象已经存在
         *          pringln方法已经存在
         *          =====》可以使用方法引用来优化表达式
         *          就是使用system.out方法直接引用(调用)pringln方法。
         */
        printString(System.out::println);
    }

结果输出:

quan
quan

 

 

 

 

通过对象名引用成员方法

最常见的一种用法,其实就是上面的做法:

/**
 * 通过对象名引用成员方法
 * 前提:
 *      对象名存在,方法名存在
 *  就可以使用对象名来引用成员方法
 */

例子:

1先创建对象类

public class MethodRefObject {
    public void pringUpperCaseString(String s){
        System.out.println(s.toUpperCase());
    }
}

2创建函数式接口

@FunctionalInterface
public interface Printable {
    //定义字符串的抽象方法
    void print(String s);
}

3测试方法:

public class Demo01MethodRefObject {
    private static void pringString(Printable p){
        p.print("quan");
    }

    public static void main(String[] args) {

        pringString((s)->{
            //创建MethodRefObject对象
            MethodRefObject obj = new MethodRefObject();
            //调用对象里面的成员方法pringUpperCaseString把字符
            //串按照大写输出
            obj.pringUpperCaseString(s);
        });

        //使用方法引用优化,先创建MethodObject对象
        MethodRefObject obj = new MethodRefObject();
        pringString(obj::pringUpperCaseString);
    }
}
/**
 * re:
 * QUAN
 * QUAN
 **/

 

通过类名称引用静态方法

/**
 * 通过类名引用静态承焰方法
 * 前提:
 *      类已经存在,静态成员方法存在
 *
 */

例子:

public class Demo01StaticMethodReference {
    //定义一个方法,方法的参数传递要计算的整数和函数式接口Calcable
    private static int method(int num,Calcable c){
       return c.calAbs(num);
    }

    public static void main(String[] args) {
        //调用method方法
        int i =method(-10,(n)->{
            //计算绝对值,使用的是Math类当中的静态方法abs
            return Math.abs(n);
        });
        System.out.println(i);

        /**
         *使用方法引用优化Lambda表达式
         *  Math类存在
         *  abs计算绝对值静态方法存在
         */
        int i1 = method(-10,Math::abs);
        System.out.println(i1);
    }


}

 

通过supper引用父类的成员方法

存在子父关系

创建一个父类

//父类
public class Human {
    public void sayHello(){
        System.out.println("say hello");
    }
}

创建一个函数式接口

@FunctionalInterface
public interface Greetable {
    void greet();
}

创建一个子类:

public class Man extends Human{
    @Override
    public void sayHello() {
        System.out.println("hello,I'm Man");
    }

    public void method(Greetable g){
        g.greet();
    }


    public void show(){
        method(()->{
            //创建父类
            Human human =  new Human();
            human.sayHello();
        });
        /**
         * 存在子夫类关系,存在super关键字,代表父类
         * 直接通过super调用父类成员方法
         */
        method(()->{
            super.sayHello();
        });
        /**
         * 通过super引用类的成员方法
         */
        method(super::sayHello);

    }

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

结果:

say hello
say hello
say hello
hello,I'm Man

 

通过this引用成员方法

this代表当前对象,如果需要引用的方法就是当前类中的成员方法。

可以使用this::成员方法来使用方法引用

定义一个接口

@FunctionalInterface
public interface Richable {
    void buy();
}

 

/**
 * 通过this引用奔雷成员方法
 */
public class Husbard {
    public void buyHome(){
        System.out.println("买房子");
    }


    public void marry(Richable r){
        r.buy();
    }

    public void soHappy(){
        marry(()->{
            //使用this成员方法
            this.buyHome();
        });
        /**
         * 使用方法引用优化Lambda表达式
         */
        marry(this::buyHome);
    }

    public static void main(String[] args) {
        new Husbard().soHappy();
    }

}

 

类的构造器引用

构造器和类名完全一致,所以使用方式为:类名称::new的格式表示。

定义一个函数式接口

/**
 * 定义一个创建Person对象的函数式接口
 */
@FunctionalInterface
public interface PersonBuilder {
    //根据姓名创建Person对象返回
    Person builderPerson(String name);
}

一个要被创建的类Person

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;
    }
}

 

/**
 * 类的构造器引用
 */
public class Demo {
    public static void printName(String name,PersonBuilder builder){
        Person person = builder.builderPerson(name);
        System.out.println(person.getName());
    }


    public static void main(String[] args) {
        printName("quan",(name)->{
            return  new Person(name);
        });
        /**
         * 使用方法引用优化lambda表达
         */
        printName("quan2",Person::new);
    }
}
//re:quan
//   quan2

 

数组构造器的引用

数组是Object的子类对象,同样具有构造器,但是语法不太一样

/**
 * 数组的构造器引用
 * 数组::new
 * 例子:int[]::new
 */

创建一个接口

//创建数组的函数式接口
@FunctionalInterface
public interface ArrayBuilder {
    //返回一个给定长度的int类型数组
    int[] builderArray(int length);
}

 

public class Demo1 {
    public static int[] createArray(int length,ArrayBuilder ab){
        return ab.builderArray(length);
    }

    public static void main(String[] args) {
        //调用create方法,传递数组长度和表达式
        int[] lenint = createArray(12,(len)->{
            return new int[len];
        });

        System.out.println(lenint.length);

        //优化,int[]就是数组的构造函数名字
        int[] lenint2 = createArray(15,int[]::new);
        System.out.println(lenint2.length);
    }
}
//re:12
//   15

 

posted @ 2020-09-06 09:16  小丑quan  阅读(734)  评论(0)    收藏  举报