博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JDK8新特性04 方法引用与构造器引用
阅读量:6838 次
发布时间:2019-06-26

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

 

import java.io.PrintStream;import java.util.Comparator;import java.util.function.*;/** * 一、方法引用 * lambda方法体之 --> 方法引用:若Lambda 体中的内容有方法已经实现了,我们可以使用"方法引用" * (可以理解为方法引用是Lambda 表达式的另外一种表现形式) * * * 主要有三种语法格式: * * 对象::实例方法名 * * 类::静态方法名 * * 类::实例方法名 * * 注意: *  1)Lambda 体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的函数列表和返回值类型保持一致! *  2) 若Lambda参数列表中的第一参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用 ClassName::method   *      ClassName代表第一个参数的类型,也代表方法调用者的类型 *      method的参数类型需要等同于第二个参数的类型 * * 二、构造器引用 *  格式: *  ClassName:new *      注意:需要调用的构造器参数列表要与函数式接口中抽象方法的参数列表保持一致 *  三、数组引用 * */public class MethodRef {    public static void main(String[] args) {        test01();        test02();        test03();        test04();        test05();        test06();        test07();    }    /**     * 对象::实例方法名     */    public static void test01() {        PrintStream out = System.out;        //1.lambda表达式  --> 方法的实现        Consumer
con2 = (x) -> out.println(x); //2.lambda对象方法的引用 --> 方法的引用 // 前提:引用的方法的参数列表和返回值类型 要与函数式接口的方法的 参数列表和返回值类型一致 Consumer
con = System.out::println; con.accept("abcdef"); } /** * 对象::实例方法名 */ public static void test02() { Employee emp = new Employee(); Supplier
sup1 = () -> emp.getName(); //lambda方法体:对匿名类创建的写法的简化 String name = sup1.get(); System.out.println(name); System.out.println("---------------"); Supplier
sup2 = emp::getAge; //lambda之方法引用:对lambda方法体的引用 Integer age = sup2.get(); System.out.println(age); } //类::静态方法名 public static void test03() { Comparator
com = (x,y) -> Integer.compare(x,y); Comparator
com2 = Integer::compare; } /** * 类::实例方法名 * 前提条件: * 若Lambda参数列表中的第一参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用 ClassName::method * ClassName代表第一个参数的类型,也代表方法调用者的类型 * method的参数类型需要等同于第二个参数的类型 */ public static void test04() { BiPredicate
pre = (x,y) -> x.equals(y); BiPredicate
pre2 = String::equals; } /** * 构造器引用 无参数构造器 */ public static void test05() { Supplier
sup = () -> new Employee(); Employee emp = sup.get(); System.out.println(emp); System.out.println("----------"); Supplier
sup2 = Employee::new; Employee emp2 = sup2.get(); System.out.println(emp2); } /** * 构造器引用 有参数构造器,根据参数类型自动判断 */ public static void test06() { Function
fun = (x) -> new Employee(x); Employee emp = fun.apply(1); System.out.println(emp); System.out.println("----------"); Function
fun2 = Employee::new;//泛型中参数类型是Integer Employee emp2 = fun2.apply(2); //构造器一个参数,自动根据参数类别判断 System.out.println(emp2); System.out.println("----------"); Function
fun3 = Employee::new; //泛型中参数类型是String Employee emp3 = fun3.apply("hello world");//构造器一个参数,自动根据参数类别判断 System.out.println(emp3); } /** * 数组引用 */ public static void test07() { Function
fun = (x) -> new String[x]; String[] arr = fun.apply(10); System.out.println(arr); System.out.println("----------"); Function
fun2 = String[]::new;//泛型中参数类型是Integer String[] arr2 = fun2.apply(20); //构造器一个参数,自动根据参数类别判断 System.out.println(arr2); }}

 

类的成员方法不能是静态的,而这个情况其实和静态方法类似,区别是,Lambda表达式的参数个数需要等于所调用方法的入参个数加一。

为什么要加一?

因为类的成员方法不能通过类名直接调用,只能通过对象来调用,也就是Lambda表达式的第一个参数,是方法的调用者,从第二个开始的参数个数要和需要调用方法的入参个数一致即可。如下图所示:

 

 

对于上面的例子,如果要对List中的每个对象执行一次它的repair方法:

cars.forEach(c -> c.repair());

根据上图,这里参数只有一个,而repair方法没有入参,所以不存在歧义,即可以改写为对应的方法引用:

cars.forEach(Car::repair);

 

 

转载于:https://www.cnblogs.com/guchunchao/p/10310737.html

你可能感兴趣的文章
PAT乙级-1057. 数零壹(20)
查看>>
总结:函数、方法与对象
查看>>
四则运算2
查看>>
ios开发 第三天
查看>>
树形动态规划 fjutoj-2131 第四集,聚集城市
查看>>
Unity3D的坑系列:你真想发布WinPhone版吗?
查看>>
angularJS中的事件
查看>>
前端面试题2
查看>>
linux 条件
查看>>
配置JAVA环境
查看>>
hdu5666 BestCoder Round #80
查看>>
linux下备份mysql命令
查看>>
mybatis由浅入深day02_4多对多查询_多对多查询总结
查看>>
关于Android连载(3)Android程序开发指南【转载】
查看>>
leetcode532
查看>>
架构设计(二)
查看>>
表单验证提交内容不能为空的几种方法
查看>>
QT项目性能调优小记
查看>>
通过button将form表单的数据提交到action层
查看>>
九度 1357 疯狂地Jobdu序列
查看>>