博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lambda03 方法引用、类型判断、变量引用
阅读量:4321 次
发布时间:2019-06-06

本文共 11834 字,大约阅读时间需要 39 分钟。

 

 

1 方法引用

  1.1 方法引用的好处

    方法引用结合 Lambda 可以引用已存在的方法,省略很多编码,而且可读性更强,它可以自动装配参数与返回值。

    在编写lambda表达式的时候可以通过方法引用的方式来简化编写流程,例如:

  1.2 静态方法引用

    格式 -> 类名 :: 方法名

    1.2.1 创建一个Student类

class Student {    private String name = "王杨帅";    public static void info(Student student) {        System.out.println(student.name + "正在学习IT技能");    }    @Override    public String toString() {        return this.name;    }}
View Code

   1.2.2 引用

    在Lambda表达式中引用Student类中的静态方法info

    Student :: info

    技巧01:info 方法是一个静态方法,它的参数中没有this

    技巧02:info 方法接收一个Student类型的参数,没有返回参数;所以 Student :: info 这个引用的结果是一个Consumer类型的实例

 

package demo_test;import java.util.function.Consumer;import java.util.function.Supplier;/** * @author 王杨帅 * @create 2018-07-30 9:54 * @desc **/public class TestDemo02 {    public static void main(String[] args) {        Student student = new Student();        Consumer
consumer = Student :: info; consumer.accept(new Student()); }}class Student { private String name = "王杨帅"; public static void info(Student student) { System.out.println(student.name + "正在学习IT技能"); } @Override public String toString() { return this.name; }}
View Code

 

  1.3 实例方法引用

    格式 -> 实例名 :: 方法名

    1.3.1 重构Student类

      新增一个money成员变量,新增一个useMoney成员方法

class Student {    private String name = "王杨帅";    private Double money = 100d;    public static void info(Student student) {        System.out.println(student.name + "正在学习IT技能");    }    public Double useMoney(Double money) {        System.out.println(this.name + "花了" + money + "元");        return this.money -= money;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public Double getMoney() {        return money;    }    public void setMoney(Double money) {        this.money = money;    }    @Override    public String toString() {        return this.name;    }}
View Code

    1.3.2 引用01【推荐方式】

      利用实例变量引用

      》创建一个Student实例student

      》引用格式:student :: useMmoney

      》技巧01:useMoney方法接收一个Double类型参数,返回一个Double类型的参数;所以 student :: useMmoney 引用返回的结果应该是一个Function类型的实例

package demo_test;import java.util.function.Consumer;import java.util.function.Function;import java.util.function.Supplier;/** * @author 王杨帅 * @create 2018-07-30 9:54 * @desc **/public class TestDemo02 {    public static void main(String[] args) {//        demo01();        Student student = new Student();        Function
function = student :: useMoney; System.out.println(student.getName() + "还剩下" + function.apply(10d) + "元"); } /** * 静态方法的引用 */ public static void demo01() { Student student = new Student(); Consumer
consumer = Student :: info; consumer.accept(new Student()); }}class Student { private String name = "王杨帅"; private Double money = 100d; public static void info(Student student) { System.out.println(student.name + "正在学习IT技能"); } public Double useMoney(Double money) { System.out.println(this.name + "花了" + money + "元"); return this.money -= money; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } @Override public String toString() { return this.name; }}
View Code

    1.3.3 引用02【不推荐使用】

      利用类来引用

      》实体类不做任何修改

      》引用格式:Student :: useMoney

      》技巧01:由于useMoney里面用到了this关键字,所以在利用类名来引用实例方法时必须传入一个Student类型的实参,Student类中的userMoney方法不需要进行更改是因为JDK会默认给实例方法第一个参数设为this;所以 Student :: useMoney 返回的是一个 BiFunction 类型的实例

package demo_test;import java.util.function.BiFunction;import java.util.function.Consumer;import java.util.function.Function;import java.util.function.Supplier;/** * @author 王杨帅 * @create 2018-07-30 9:54 * @desc **/public class TestDemo02 {    public static void main(String[] args) {//        demo01();//        demo02();        BiFunction
biFunction = Student :: useMoney; Student student = new Student(); System.out.println(student.getName() + "还剩下" + biFunction.apply(student, 11d) + "元"); } /** * 实例引用01【推荐方式】 */ public static void demo02() { Student student = new Student(); Function
function = student :: useMoney; System.out.println(student.getName() + "还剩下" + function.apply(10d) + "元"); } /** * 静态方法的引用 */ public static void demo01() { Student student = new Student(); Consumer
consumer = Student :: info; consumer.accept(new Student()); }}class Student { private String name = "王杨帅"; private Double money = 100d; public static void info(Student student) { System.out.println(student.name + "正在学习IT技能"); } public Double useMoney(Double money) { System.out.println(this.name + "花了" + money + "元"); return this.money -= money; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } @Override public String toString() { return this.name; }}
View Code

  1.4 构造器的引用

    格式 -> Student :: new 

    1.4.1 重构Student类

      添加一个无参构造器和有参构造器

class Student {    private String name = "王杨帅";    private Double money = 100d;    public Student() {    }    public Student(String name, Double money) {        this.name = name;        this.money = money;    }    public static void info(Student student) {        System.out.println(student.name + "正在学习IT技能");    }    public Double useMoney(Double money) {        System.out.println(this.name + "花了" + money + "元");        return this.money -= money;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public Double getMoney() {        return money;    }    public void setMoney(Double money) {        this.money = money;    }    @Override    public String toString() {        return this.name;    }}
View Code

    1.4.2 无参构造器的引用

      》引用格式:Student :: new 

      》无参构造器没有输入参数,输出参数是一个Student类型,所以 Student :: new 的返回的是一个 Supplier 类型的实例

package demo_test;import java.util.function.BiFunction;import java.util.function.Consumer;import java.util.function.Function;import java.util.function.Supplier;/** * @author 王杨帅 * @create 2018-07-30 9:54 * @desc **/public class TestDemo02 {    public static void main(String[] args) {//        demo01();//        demo02();//        demo03();        Supplier
supplier = Student :: new; System.out.println(supplier.get()); } /** * 实例引用02【不推荐使用】 */ public static void demo03() { BiFunction
biFunction = Student :: useMoney; Student student = new Student(); System.out.println(student.getName() + "还剩下" + biFunction.apply(student, 11d) + "元"); } /** * 实例引用01【推荐方式】 */ public static void demo02() { Student student = new Student(); Function
function = student :: useMoney; System.out.println(student.getName() + "还剩下" + function.apply(10d) + "元"); } /** * 静态方法的引用 */ public static void demo01() { Student student = new Student(); Consumer
consumer = Student :: info; consumer.accept(new Student()); }}class Student { private String name = "王杨帅"; private Double money = 100d; public Student() { } public Student(String name, Double money) { this.name = name; this.money = money; } public static void info(Student student) { System.out.println(student.name + "正在学习IT技能"); } public Double useMoney(Double money) { System.out.println(this.name + "花了" + money + "元"); return this.money -= money; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } @Override public String toString() { return this.name; }}
View Code

    1.4.3 有参构造器的引用

      》引用格式:Student :: new 

        疑惑:为什么有参构造器和无参构造器的输入参数都不一样,为什么引用格式一样呢?

        解惑:lambda表达式的引用会自动进行以引用类型判断,自己去寻找符合条件的方法执行,开发人员无需担心弄错

      》有参构造器有两个输入参数,输出参数也是一个Student类型,所以 Student :: new  返回的是一个  BiFunction 类型的实例

package demo_test;import java.util.function.BiFunction;import java.util.function.Consumer;import java.util.function.Function;import java.util.function.Supplier;/** * @author 王杨帅 * @create 2018-07-30 9:54 * @desc **/public class TestDemo02 {    public static void main(String[] args) {//        demo01();//        demo02();//        demo03();        BiFunction
biFunction = Student :: new; System.out.println(biFunction.apply("三少", 100d)); } /** * 实例引用02【不推荐使用】 */ public static void demo03() { BiFunction
biFunction = Student :: useMoney; Student student = new Student(); System.out.println(student.getName() + "还剩下" + biFunction.apply(student, 11d) + "元"); } /** * 实例引用01【推荐方式】 */ public static void demo02() { Student student = new Student(); Function
function = student :: useMoney; System.out.println(student.getName() + "还剩下" + function.apply(10d) + "元"); } /** * 静态方法的引用 */ public static void demo01() { Student student = new Student(); Consumer
consumer = Student :: info; consumer.accept(new Student()); }}class Student { private String name = "王杨帅"; private Double money = 100d; public Student() { } public Student(String name, Double money) { this.name = name; this.money = money; } public static void info(Student student) { System.out.println(student.name + "正在学习IT技能"); } public Double useMoney(Double money) { System.out.println(this.name + "花了" + money + "元"); return this.money -= money; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } @Override public String toString() { return this.name; }}
View Code

 

2 类型判断

  lambda表达式的返回结果是一个函数式接口类型的实例,lambda表达式的结果具体对应哪一个函数式接口类型有JDK自己进行判断;当然开发者如果清楚自己在做什么可以对lambda表达式的记过进行强制类型转换。

  2.1 准备代码

    》创建两个函数式接口

interface IMatch {    Integer add(Integer a, Integer b);}interface IMatch02 {    Integer add(Integer a, Integer b);}
View Code

  2.2 类型判断分类

    2.2.1 变量赋值

    2.2.2 数组定义

    2.2.3 强制转换

    2.2.4 方法返回值

    2.2.5 实际使用

      一个方法的参数是一个函式接口,我们就可以利用lambda表达式了类型推断来实现;这种方式其实和类型定义是一样的

      技巧01:重载方法引起lambda表达式不知道应该对应哪个函数接口时可以通过强制类型转化来实现

 

3 变量引用

  3.1 在lambda表达式中使用this关键字

    3.1.1 lambda表达式中this指向的是当前类

      原因:lambda 表达式是函数式接口的实现类实例,所以,定义 lambda 表达式,实际上要经历两件事情。第一件事情是定义函数式接口实现类,第二件事情是创建该实现类实例。 this 称之为当前对象,但是, 定义 lambda 表达式时,也就是定义函数式接口实现类时, lambda 表达式代表的实现类本身没有 this 对象,此时若是使用 this 对象,指的是把 lambda 表达式围住的类的当前对象,而不是 lambda 表达式代表的实现类的当前对象。

/**     * notes:     *      1 java是传值的     *      2 匿名内部类中的this是指向内部类,lambda表达式的this是执行当前类     *      3 匿名内部类和lambda表达式引用当前类的变量时都需要时final修饰的成员,java8开始     *  可以不用final修饰,是因为jdk在编译的时候帮我们做了     *      4 引用的成员需要final修饰的原因时保证当前类的成员变量和匿名内部类或者labmda表达     *  式中应用的变量都指向同一个对象,如果没有final修饰,就很容易导致两个变量执行不同的变量,     *  从而导致程序出现一些bug     */

 

转载于:https://www.cnblogs.com/NeverCtrl-C/p/9222188.html

你可能感兴趣的文章
request和response的知识
查看>>
bootstrap 表单类
查看>>
20165332第四周学习总结
查看>>
Codeforces Round #200 (Div. 1)D. Water Tree dfs序
查看>>
linux安全设置
查看>>
Myflight航班查询系统
查看>>
团队-团队编程项目爬取豆瓣电影top250-代码设计规范
查看>>
【linux驱动分析】之dm9000驱动分析(六):dm9000_init和dm9000_probe的实现
查看>>
json具体解释
查看>>
十一:Java之GUI图形Awt和Swing
查看>>
.net在arraylist用法
查看>>
android程序报错“error launching activity com.android.ddmlib.shellcommandunresponsiveexception”的解决方式...
查看>>
ORACLE中CONSTRAINT的四对属性
查看>>
DbVisualizer Pro 9.5.2中文乱码问题
查看>>
numpy.tile()
查看>>
[bzoj3944] Sum
查看>>
hadoop2.7节点的动态增加与删除
查看>>
Ogre: 天空
查看>>
关于NSDictionary的一点感悟
查看>>
CSS长度单位:px和pt的区别
查看>>