美文网首页
八 JDK8新特性——第四节 方法引用-优化Lambda

八 JDK8新特性——第四节 方法引用-优化Lambda

作者: 杜艳_66c4 | 来源:发表于2022-07-13 10:42 被阅读0次

    1、方法引用基本介绍

    主要对Lambda表达式的优化
    在使用Lambda表达式的时候,实际上传递进去的是代码就是一种解决方案,拿什么参数做什么需求,那么考虑一种情况,如果我们在Lambda中所指的操作方案,已经有地方有相同方案,是否需重复?

    Lambda要有函数式接口,定义一个函数式接口

    package com.company.demo05LambdaTest;
    
    /**
     * @author 杜艳艳
     * @version 1.0
     * @date 2020/12/29 16:37
     * 定义一个打印的函数式接口,
     */
    @FunctionalInterface
    public interface Printable {
        //打印字符串的抽象方法
         void print(String s);
    }
    

    定义一个类。

    package com.company.demo05LambdaTest;
    
    /**
     * @author 杜艳艳
     * @version 1.0
     * @date 2020/12/29 16:39
     */
    public class Demo01Printable {
        //定义一个方法,参数传printable接口。对字符串打印
        public static void printString(Printable p ){
            p.print("helloword");
        }
    
        public static void main(String[] args) {
            //调用printstring方法 ,参数Printable是一个函数式接口,可以传递lambda表达式
            printString((s)->{
                System.out.println(s); //helloword
            });
            /*
     分析
            lambda 表达式的目的,打印参数传递的字符串,把参数s传递给System.out对象,调用out对象的方法println,对字符串输出
            注意:
            1、System.out对象已经存在,
            2、调用其方法println已经存在
    
           所以可以用方法引用优化lambda
           可以使用System.out直接引用(调用)println方法 ,取代Lambda, 对字符串输出,参数省略
           :: 是方法引用的运算符,表达式是方法引用表达式
           两种写法效果一样,第二种更简洁
           注意:
           Lambda中传递的参数一定是方法引用中的那个方法可以接收的类型,否则抛异常
             */
            printString(System.out::println);  //helloword
        }
    }
    
    方法引用符

    2、方法引用-通过对象名引用成员方法

    前提: 类存在,静态方法存在

    1、对象名要有实例 化的对象,所以要建一个类,实例对象, 类中定义一个成员方法, 通过类创建一个对象,来引用里面的成员方法
    类MethodRerObject

    package com.company.demo06ObjectMethod;
    
    /**
     * @author 杜艳艳
     * @version 1.0
     * @date 2020/12/30 16:48
     */
    public class MethodRerObject {
    
        //定义一个成员方法,传递字符串,按照大写输出
        public  void printUpString(String str){
            System.out.println(str.toUpperCase());
        }
    }
    

    2、函数式接口

    package com.company.demo06ObjectMethod;
    
    /**
     * @author 杜艳艳
     * @version 1.0
     * @date 2020/12/29 16:37
     * 定义一个打印的函数式接口,
     */
    @FunctionalInterface
    public interface Printable {
        //打印字符串的抽象方法
         void print(String s);
    }
    

    3、测试类

    package com.company.demo06ObjectMethod;
    
    /**
     * @author 杜艳艳
     * @version 1.0
     * @date 2020/12/30 16:51
     * 通过对象名引用成员方法
     * 使用前提:对象名存在,成员方法存在,就可以使用对象名引用成员方法
     */
    public class Demo01ObjectMethodRer {
        //定义一个方法。方法的参数传递Printable接口
        public static void printString(Printable p){
            p.print("hello");
        }
    
        public static void main(String[] args) {
            //调用printString ,方法的参数是函数式接口,可以传递lambda 表达式
            printString((s)->{
                //创建MethodRerObject对象
                MethodRerObject obj = new MethodRerObject();
                //调用对象中的成员方法printUpString,把字符串按照大写输出
                obj.printUpString(s);  //HELLO
            });
    
            /*使用方法引用优化lambda
            对象MethodRerObject已经存在, 成员方法也存在printUpString
            所以可以用对象名来引用成员方法
             */
            //创建MethodRerObject对象
            MethodRerObject obj2 = new MethodRerObject();
            printString(obj2::printUpString);  //HELLO
        }
    }
    

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

    由于在类中java.lang.Math中已经存在了静态方法abs,所以需要通过lambda 调用该方法时,有两种写法,首先是函数式接口,使用lambda , 一种是类名引用静态方法

    函数式接口

    package com.company.demo07StaticMethod;
    
    /**
     * @author 杜艳艳
     * @version 1.0
     * @date 2020/12/30 17:08
     */
    @FunctionalInterface
    public interface Calcable {
        //定义一个抽象方法,传递一个整数,对整数进行绝对值计算,并返回
        public int calAbs(int number);
    }
    

    测试类

    package com.company.demo07StaticMethod;
    
    /**
     * @author 杜艳艳
     * @version 1.0
     * @date 2020/12/30 17:11
     * 通过类名引用静态成员方法,使用前提:类名存在,静态成员方法存在;就可以直接用类名引用静态成员方法
     */
    public class Demo01StaticMethodRer {
       //定义一个方法,方法的参数传递要计算绝对值的整数 和 函数式接口Calcable
        public static int method(int number,Calcable c){
            return c.calAbs(number);
        }
    
        public static void main(String[] args) {
            //调用method 方法,传递计算绝对值的整数 和 Lambda表达式
            int num = method(-10,(n)->{
                //对参数进行绝对值的计算,并返回结果
                return Math.abs(n);
            });
            System.out.println(num);  //10
    
            /*通过类名引用静态成员方法。优化lambda表达式
            Math 存在。abs 计算绝对值的静态成员方法存在
            所以可以直接通过类名引用静态方法
             */
            int num2 = method(-10, Math::abs);
            System.out.println(num2);  //10
    
        }
    }
    

    4、方法引用-通过super引用父类的成员方法

    如果存在继承关系,当Lambda中需要出现super调用时,也可以使用方法引用进行替代
    前提: 有子父类继承关系,有函数式接口,父类有成员方法


    例子

    函数式接口

    package con.day13.demo05.SuperMethodReference;
    
    /*
    定义一个见面的函数式接口
     */
    @FunctionalInterface
    public interface Greetable {
       //定义一个见面的方法
        void greet();
    }
    

    父类

    package con.day13.demo05.SuperMethodReference;
    
    /*
    定义父类
     */
    public class Human {
        //定义一个sayhello 的方法
        public void sayHello(){
            System.out.println("父类human的sayHellO");
        }
    }
    

    子类以及主方法

    package con.day13.demo05.SuperMethodReference;
    /*
    定义子类
     */
    public class Man extends Human{
        //重写父类sayHello的方法
    
        @Override
        public void sayHello() {
            System.out.println("我是子类");
        }
    
        //定义一个方法参数传递Greetable接口
        public void method(Greetable g){
            g.greet();
        }
    
        public void show(){
            //调用method 方法,方法的参数是函数式接口,可传递Lambda
           /* method(()->{
                //创建父类对象
                Human h = new Human();
                //调用父类的sayHello
                h.sayHello();
            });*/
            //因为有子父类关系,可以存在一个关键字super 所以我们可以直接用super调用父类的成员方法
    
           /* method(()->{
                super.sayHello();    //父类human的sayHellO
            });*/
    
            //继续简化, 使用super引用父类的成员方法, super 已经存在,sayHello 已经存在,
            //所以可直接使用super引用父类的成员方法
            //父类human的sayHellO
            method(super::sayHello);
        }
    
        public static void main(String[] args) {
            new Man().show();  //父类human的sayHellO
        }
    }
    

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

    this

    函数式接口

    package con.day13.demo05.ThisMethodReference;
    
    /*
    定义一个函数式接口
     */
    @FunctionalInterface
        public interface Richable {
            //想买什么就买什么的方法
            void buy();
        }
    

    方法:

    package con.day13.demo05.ThisMethodReference;
    
    /*
    通过this引用本类的成员方法
     */
    public class Husband {
        //定义一个买房子的方法
        public void buyHouse(){
            System.out.println("买到房子啦");
        }
        //定义结婚方法,参数传递Richable接口
        public void marry(Richable r){
            r.buy();
        }
    
    /*    //定义一个非常高兴的方法
        public void soHappy(){
            //调用结婚方法。方法的参数Richable 是一个函数式接口,用Lambda
            marry(()->{
                //使用this.成员方法,调用本类买房子的方法
                this.buyHouse();  //买到房子啦
            });
        }*/
    
        //简化, 方法引用
    
        //定义一个非常高兴的方法
        public void soHappy(){
            //调用结婚方法。方法的参数Richable 是一个函数式接口,用Lambda
            marry(this::buyHouse);  //买到房子啦;
        }
    
    
        public static void main(String[] args) {
            Husband husband = new Husband();
            husband.soHappy();
        }
    }
    

    6、 方法引用-类的构造器引用

    Person 类

    package con.day13.demo05.ConstructorMethodReference;
    
    public class Person {
        private String name;
    
        public Person(String name) {
            this.name = name;
        }
    
        public Person() {
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    

    函数式接口

    package con.day13.demo05.ConstructorMethodReference;
    //创建Perso对象的函数式接口
    @FunctionalInterface
    public interface PersonBuilder {
        //定义一个方法,根据传递的姓名,创建Person 对象返回
        Person builderPerson(String name);
    }
    

    方法类

    package con.day13.demo05.ConstructorMethodReference;
    
    /*
    类的构造器引用
     */
    public class Demo {
        //定义一个方法,参数传递姓名和PersonBuilder接口,方法中通过姓名创建Person对象
        public static void pringName(String name, PersonBuilder pb){
            Person person = pb.builderPerson(name);
            System.out.println(person.getName()); //迪丽热巴
        }
    
    /*    public static void main(String[] args) {
            //调用pringName方法,方法的参数是PersonBuilder ,函数式接口,用Lambda
            pringName("迪丽热巴",(String name)->{
                return new Person(name);
            });
        }*/
    /*使用方法引用,优化
    构造方法new Person(String name)已知
    创建对象已经new
    就可以使用Person引用new创建对象
        */
        public static void main(String[] args) {
            //调用pringName方法,方法的参数是PersonBuilder ,函数式接口,用Lambda
            pringName("迪丽热巴", Person::new);
        }
    }
    

    7、方法引用-数组的构造引用

    相关文章

      网友评论

          本文标题:八 JDK8新特性——第四节 方法引用-优化Lambda

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