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

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

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

    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<Double, Double> function = student :: useMoney;
System.out.println(student.getName() + "还剩下" + function.apply(10d) + "元"); } /**
* 静态方法的引用
*/
public static void demo01() {
Student student = new Student(); Consumer<Student> 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;
}
}

    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<Student, Double, Double> 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<Double, Double> function = student :: useMoney;
System.out.println(student.getName() + "还剩下" + function.apply(10d) + "元");
} /**
* 静态方法的引用
*/
public static void demo01() {
Student student = new Student(); Consumer<Student> 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;
}
}

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

    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<Student> supplier = Student :: new;
System.out.println(supplier.get()); } /**
* 实例引用02【不推荐使用】
*/
public static void demo03() {
BiFunction<Student, Double, Double> 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<Double, Double> function = student :: useMoney;
System.out.println(student.getName() + "还剩下" + function.apply(10d) + "元");
} /**
* 静态方法的引用
*/
public static void demo01() {
Student student = new Student(); Consumer<Student> 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;
}
}

    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<String, Double, Student> biFunction = Student :: new;
System.out.println(biFunction.apply("三少", 100d)); } /**
* 实例引用02【不推荐使用】
*/
public static void demo03() {
BiFunction<Student, Double, Double> 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<Double, Double> function = student :: useMoney;
System.out.println(student.getName() + "还剩下" + function.apply(10d) + "元");
} /**
* 静态方法的引用
*/
public static void demo01() {
Student student = new Student(); Consumer<Student> 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;
}
}

2 类型判断

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

  2.1 准备代码

    》创建两个函数式接口

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

  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
*/

Lambda03 方法引用、类型判断、变量引用的更多相关文章

  1. php引用计数与变量引用

    每个php5.5变量都存储在一个叫做zval的变量容器中. 一个zval变量容器,除了包含变量的类型与值外,还包含两个字节的额外信息: 1.第一个是“is_ref”,是个bool型,用来标识这个变量是 ...

  2. console.log、toString方法与js判断变量类型

    Java调用system.print.out()是会调用toString方法打印js里的console.log也是控制台打印,很多时候,我们以为也是调用toString方法,其实并不是.我们在chro ...

  3. JavaScript中判断变量类型最简洁的实现方法以及自动类型转换(#################################)

    这篇文章主要介绍了JavaScript中判断整字类型最简洁的实现方法,本文给出多个判断整数的方法,最后总结出一个最短.最简洁的实现方法,需要的朋友可以参考下 我们知道JavaScript提供了type ...

  4. C# 异常:从作用域“”引用了“FiasHostApp.Entity.DBEntity.FIAS_RM_v1.ITraNetMgrUnitBaseInfoRecord”类型的变量“w”,但该变量未定义

    C# 异常:从作用域“”引用了“FiasHostApp.Entity.DBEntity.FIAS_RM_v1.ITraNetMgrUnitBaseInfoRecord”类型的变量“w”,但该变量未定义 ...

  5. python list类型的变量相当于全局变量 可以被函数与类引用

    python list类型的变量相当于全局变量 可以被函数与类引用

  6. Java 中 父类变量访问子类方法 需要使用 类型转换 (instenceof)关键字 /类型判断/

    通过数组元素访问方法的时候只能访问在 Animal中定义的方法,对 于 Tiger类和  Fish中定义的方法时却不能调用,例如语句  animal[2].swim();就是不正确的.当 需要访问这些 ...

  7. JS 中对变量类型判断的几种方式

    文章整理搬运,出处不详,如有侵犯,请联系~   数据类型判断和数据类型转换代码工具 在 JS 中,有 5 种基本数据类型和 1 种复杂数据类型,基本数据类型有:Undefined, Null, Boo ...

  8. 关于java内存泄露的总结--引用的类型:强引用,弱引用,软引用

    今天面试了一家公司的java开发方面的实习生,被问到一个问题:如何处理java中的内存泄露问题,保证java的虚拟机内存不会被爆掉,当时其实觉得面试官的问题有点泛,所以也没有很好领会他的意思,答案也不 ...

  9. 2.8 补充:shell变量引用方式

    一 变量   变量:本质上是程序中保存用户数据的一块内存空间,变量名就是内存空间地址.   Shell中:变量可由字母数字和下划线组成,以字母或下划线开头.   命名:PATH=/sbin       ...

随机推荐

  1. WPF XMAL获取元素的父元素,子元素

    /// 获得指定元素的父元素 /// </summary> /// <typeparam name="T">指定页面元素</typeparam> ...

  2. 浅谈如何在SQL Server中生成脚本

    在生成脚本过程中,有很多参数可以选择,合理的配置这些参数,可以让我们很方便的按照我们的期望生成脚本. 生成脚本的一些选项,如下图: 我这里是SQL 2005 的选项, SQL 2008 的选项跟这个稍 ...

  3. 【JQuery】学习

    JavaScript参考 JQuery 学习总结及实例 1.JQuery概念 A.Jquery是一个优秀的Javascript框架.它是轻量级的js库 ,它兼容CSS3,还兼容各种浏览器,jQuery ...

  4. 【转】IUSR和IIS_IUSRS

    转自:http://blog.chinaunix.net/uid-20344928-id-3306130.html   概述   在早期的IIS版本中,随着IIS的安装,系统会创建一个IUSR_Mac ...

  5. utf_8 和 GBK 不搭出现乱码(转)

    今天调数据的时候发现调出来的一直是乱码,用了各种方法都未解决,简单的调数据用了好长时间,最后突然发现了一个问题 页面的 <meta http-equiv="Content-Type&q ...

  6. 从ROS bag文件中提取图像

    从ROS bag文件中提取图像 创建launch文件,如下: export.launch <launch> <node pkg="rosbag" type=&qu ...

  7. Java 泛型分析

    Java 泛型 Java Generics 是 JDK 1.5 引入的新特性,它提供了编译时的类型安全检测机制,避免了代码中进行显示的类型转换(cast),是对类型系统的一种增强. Java Gene ...

  8. Netty实现原理浅析

    1.总体结构 先放上一张漂亮的Netty总体结构图,下面的内容也主要围绕该图上的一些核心功能做分析,但对如Container Integration及Security Support等高级可选功能,本 ...

  9. python's fourth day for me 列表

    break 可以打断 for 循环不执行 else 语句 s = 'fdddsadwes' for i in s: if i == 's': break #可跳出for循环且不用执行else语句 pr ...

  10. storm和kafka整合

    storm和kafka整合 依赖 <dependency> <groupId>org.apache.storm</groupId> <artifactId&g ...