美文网首页
[java]20、方法引用

[java]20、方法引用

作者: 史记_d5da | 来源:发表于2021-10-23 15:22 被阅读0次

    1、Lambda表达式优化

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

    public class Demo01Printable {
        //定义一个方法,参数传递Printable接口,对字符串进行打印
        public static void printString(Printable p) {
            p.print("HelloWorld");
        }
        public static void main(String[] args) {
            //调用printString方法,方法的参数Printable是一个函数式接口,所以可以传递Lambda
            printString((s) -> {
                System.out.println(s);
            });
            /*
                分析:
                    Lambda表达式的目的,打印参数传递的字符串
                    把参数s,传递给了System.out对象,调用out对象中的方法println对字符串进行了输出
                    注意:
                        1.System.out对象是已经存在的
                        2.println方法也是已经存在的
                    所以我们可以使用方法引用来优化Lambda表达式
                    可以使用System.out方法直接引用(调用)println方法
             */
            printString(System.out::println);
        }
    }
    
    

    2、使用对象名引用成员方法

    // Printable interface
    @FunctionalInterface
    public interface Printable {
        void print(String s);
    }
    // MethodRefObject.java
    public class MethodRefObject {
        // 定义成员方法
        public void printUpperCaseString(String str) {
            System.out.println(str.toUpperCase());
        }
    }
    // Demo01ObjectMethodReference.java
    // 通过对象名引用成员方法
    // 使用前提是对象名是已经存在的,成员方法也是已经存在的
    public class Demo01ObjectMethodReference {
        public static void printString(Printable p) {
            p.print("Hello World");
        }
    
        public static void main(String[] args) {
            printString(s -> {
                MethodRefObject obj = new MethodRefObject();
                obj.printUpperCaseString(s);
            });
    
            // 使用对象名引用成员方法
            printString(new MethodRefObject()::printUpperCaseString);
        }
    }
    

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

    // Calcable
    @FunctionalInterface
    public interface Calcable {
        int calsAbs(int number);
    }
    // Demo01StaticMethodReference
    public class Demo01StaticMethodReference {
        public static void main(String[] args) {
            int num = method(-10, n-> {
                return Math.abs(n);
            });
            System.out.println(num);
            // 静态方法引用
            System.out.println(method(-10, Math::abs));
    
        }
        // 定义一个方法,方法的参数要定义一个绝对值的整数,和函数式接口 calcable
        public static int method(int number, Calcable c) {
            return c.calsAbs(number);
        }
    }
    
    

    4、通过super引用成员方法

    如果存在继承关系,当Lambda中需要出现super调用时,也可以使用方法引用进行代替

    // Greetable interface
    @FunctionalInterface
    public interface Greetable {
        void greet();
    }
    // 父类 Human.java
    public class Human {
        public void sayHello() {
            System.out.println("Hello 我是Human");
        }
    }
    // 子类 Man.java
    public class Man extends Human{
        // 重写
        @Override
        public void sayHello() {
            System.out.println("Hello 我是man");
        }
        public void method(Greetable g) {
            g.greet();
        }
        public void show() {
            // 调用method方法
            method(()-> {
                Human h = new Human();
                h.sayHello();
            });
            // 因为存在子父类关系,所以存在的一个关键字super,代表父类,我们可以直接使用super调用父类的成员方法
            method(()-> {
                super.sayHello();
            });
            // 使用super引用成员方法,super是存在的,父类的sayHello也是存在的,所以可以直接使用super引用父类的成员方法
            method(super::sayHello);
        }
    
        public static void main(String[] args) {
            new Man().show();
        }
    }
    

    5、使用this引用本类的成员方法

    // Richable interface
    @FunctionalInterface
    public interface Richable {
        void buy();
    }
    // Husband.java
    
    // 通过this引用本类的成员方法
    public class Husband {
        public void buyHouse() {
            System.out.println("北京二环内买一套四合院");
        }
    
        public void marry(Richable r) {
            r.buy();
        }
    
        public void soHappy() {
            marry(() -> {
                this.buyHouse();
            });
            // 优化lambda表达式,this已经存在,buyHouse已经存在的
            marry(this::buyHouse);
        }
    
        public static void main(String[] args) {
            new Husband().soHappy();
        }
    }
    

    6、使用类构造器引用

    // PersonBuilder interface
    @FunctionalInterface
    public interface PersonBuilder {
        // 定义一个方法,根据传递的姓名,创建Person对象
        Person builderPerson(String name);
    }
    // Person.java
    public class Person {
        private String name;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Person() {
        }
        public Person(String name) {
            this.name = name;
        }
    }
    // Demo.java
    // 类的构造器
    public class Demo {
        public static void printName(String name, PersonBuilder pb) {
            Person person = pb.builderPerson(name);
            System.out.println(person.getName());
        }
    
        public static void main(String[] args) {
            printName("迪丽热巴", (name)-> {
                return new Person(name);
            });
            /*使用方法引用优化Lambda表达式
            * 构造方法new Person已知
            * 创建对象的方式也是已知的new
             */
            printName("迪丽热巴", Person::new);
        }
    }
    

    7、数组的构造器引用

    // ArrayBuilder interface
    @FunctionalInterface
    public interface ArrayBuilder {
        // 定义一个创建int类型数组的方法
        int[] builderArray(int length);
    }
    // Demo.java
    // 数组的构造器引用
    public class Demo {
         public static int[] createArray(int length, ArrayBuilder ab) {
             return ab.builderArray(length);
         }
    
        public static void main(String[] args) {
            int []arr1 = createArray(10, (len)->{ return  new int[len]; });
            System.out.println(arr1.length);
            /*
            * 使用lambda
            * 已知创建的数组是 int[] 数组
            * 数组的长度也是已知的
            * 就可以使用方法引用
            * int[] 引用new,根据参数传递的长度来创建数组
            * */
            int[] arr2 = createArray(10, int[]::new);
            System.out.println(arr2.length);
        }
    }
    

    相关文章

      网友评论

          本文标题:[java]20、方法引用

          本文链接:https://www.haomeiwen.com/subject/qwukaltx.html