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<String> con2 = (x) -> out.println(x); //2.lambda对象方法的引用 --> 方法的引用
// 前提:引用的方法的参数列表和返回值类型 要与函数式接口的方法的 参数列表和返回值类型一致
Consumer<String> con = System.out::println;
con.accept("abcdef");
} /**
* 对象::实例方法名
*/
public static void test02() {
Employee emp = new Employee();
Supplier<String> sup1 = () -> emp.getName(); //lambda方法体:对匿名类创建的写法的简化
String name = sup1.get();
System.out.println(name); System.out.println("---------------");
Supplier<Integer> sup2 = emp::getAge; //lambda之方法引用:对lambda方法体的引用
Integer age = sup2.get(); System.out.println(age);
} //类::静态方法名
public static void test03() {
Comparator<Integer> com = (x,y) -> Integer.compare(x,y);
Comparator<Integer> com2 = Integer::compare;
} /**
* 类::实例方法名
* 前提条件:
* 若Lambda参数列表中的第一参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用 ClassName::method
* ClassName代表第一个参数的类型,也代表方法调用者的类型
* method的参数类型需要等同于第二个参数的类型
*/
public static void test04() {
BiPredicate<String,String> pre = (x,y) -> x.equals(y);
BiPredicate<String,String> pre2 = String::equals;
} /**
* 构造器引用 无参数构造器
*/
public static void test05() {
Supplier<Employee> sup = () -> new Employee();
Employee emp = sup.get();
System.out.println(emp); System.out.println("----------");
Supplier<Employee> sup2 = Employee::new;
Employee emp2 = sup2.get();
System.out.println(emp2);
} /**
* 构造器引用 有参数构造器,根据参数类型自动判断
*/
public static void test06() {
Function<Integer,Employee> fun = (x) -> new Employee(x);
Employee emp = fun.apply(1);
System.out.println(emp); System.out.println("----------");
Function<Integer,Employee> fun2 = Employee::new;//泛型中参数类型是Integer
Employee emp2 = fun2.apply(2); //构造器一个参数,自动根据参数类别判断
System.out.println(emp2); System.out.println("----------");
Function<String,Employee> fun3 = Employee::new; //泛型中参数类型是String
Employee emp3 = fun3.apply("hello world");//构造器一个参数,自动根据参数类别判断
System.out.println(emp3);
} /**
* 数组引用
*/
public static void test07() {
Function<Integer,String[]> fun = (x) -> new String[x];
String[] arr = fun.apply(10);
System.out.println(arr); System.out.println("----------");
Function<Integer,String[]> 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);

Java笔记——Java8特性之Lambda、方法引用和Streams

JDK8新特性04 方法引用与构造器引用的更多相关文章

  1. JDK8新特性之方法引用

    什么是方法引用 方法引用是只需要使用方法的名字,而具体调用交给函数式接口,需要和Lambda表达式配合使用. 如: List<String> list = Arrays.asList(&q ...

  2. JDK8新特性,方法的引用

    引用方法并运行 在Java中,方法和构造方法都看作是对象的一种,那么你要引用它(不是调用),则可以用::来引用.用来存储这个引用的类型用@FunctionlaInterface注解来标识. 示例: p ...

  3. java8新特性——方法引用与构造器引用

    上篇文章简单学习了java8内置得4大核心函数式接口,这类接口可以解决我们遇到得大多数得业务场景得问题.今天来简单学习一下方法引用与构造器引用. 一.方法引用 方法引用:若lambda 体中得内容已经 ...

  4. 乐字节-Java8新特性之方法引用

    上一篇小乐介绍了<Java8新特性-函数式接口>,大家可以点击回顾.这篇文章将接着介绍Java8新特性之方法引用. Java8 中引入方法引用新特性,用于简化应用对象方法的调用, 方法引用 ...

  5. 一次电话Java面试的问题总结(JDK8新特性、哈希冲突、HashMap原理、线程安全、Linux查询命令、Hadoop节点)

    面试涉及问题含有: Java JDK8新特性 集合(哈希冲突.HashMap的原理.自动排序的集合TreeSet) 多线程安全问题 String和StringBuffer JVM 原理.运行流程.内部 ...

  6. JDK8 新特性

    JDK8 新特性目录导航: Lambda 表达式 函数式接口 方法引用.构造器引用和数组引用 接口支持默认方法和静态方法 Stream API 增强类型推断 新的日期时间 API Optional 类 ...

  7. JDK8新特性一览

    转载自:http://blog.csdn.net/qiubabin/article/details/70256683 官方新特性说明地址 Jdk8新特性.png 下面对几个常用的特性做下重点说明. 一 ...

  8. JDK8新特性:使用stream、Comparator和Method Reference实现集合的优雅排序

    大家对java接口Comparator和Comparable都不陌生,JDK8里面Comparable还和以前一样,没有什么改动:但是Comparator在之前基础上增加了很多static和defau ...

  9. jdk8新特性:在用Repository实体查询是总是提示要java.util.Optional, 原 Inferred type 'S' for type parameter 'S' is not within its bound;

    jdk8新特性:在用Repository实体查询是总是提示要java.util.Optional 在使用springboot 方法报错: Inferred type 'S' for type para ...

随机推荐

  1. django从零开始-视图

    1.处理的登录请求 views文章中添加登录函数login_action def login_action(request): if request.method == 'POST': usernam ...

  2. JavaWeb基础之Servlet简单实现用户登陆

    学习javaweb遇到了一些坑,一些问题总结下来,记个笔记. 学习servlet遇到的一些坑: servlet实现用户登陆遇到的坑解决办法: https://www.cnblogs.com/swxj/ ...

  3. OpenLayers学习笔记(三)— QML与HTML通信之 地图上点击添加自由文本

    实现在地图随意点击,弹出文本输入框,输入任意文字,完成自由文本添加的功能 作者: 狐狸家的鱼 GitHub:八至 本文链接:地图上点击添加自由文本 关于如何QML与HTML通信已经在上一篇文章 QML ...

  4. Windows下VMware14黑屏

    解决方法 以管理员身份运行命令提示符,执行netsh winsock reset

  5. python random使用方法

    如果你对在Python生成随机数与random模块中最常用的几个函数的关系与不懂之处,下面的文章就是对Python生成随机数与random模块中最常用的几个函数的关系,希望你会有所收获,以下就是这篇文 ...

  6. Filter(过滤器)

    一.Filter过滤器(重要) Javaweb中的过滤器可以拦截所有访问web资源的请求或响应操作. 1.Filter快速入门 1.1.步骤: 1. 创建一个类实现Filter接口 2. 重写接口中方 ...

  7. The CLI moved into a separate package: webpack-cli.解决办法

    The CLI moved into a separate package: webpack-cli.Please install ‘webpack-cli‘ in addition to webpa ...

  8. django系列 1 :python+django环境搭建 +mac提示找不到manage.py命令

    1.安装python3 2.设置python3的环境变量 3.进入命令行模式,输入 pip install django 1.10.3 4.验证是否安装完成 pip show django 5.dja ...

  9. hystrix项目实战

    闲话少说: 总共分6步: (1)添加hystrix依赖以及监控的依赖 <dependency> <groupId>org.springframework.cloud</g ...

  10. socket编程以及select、epoll、poll示例详解

    socket编程socket这个词可以表示很多概念,在TCP/IP协议中“IP地址 + TCP或UDP端口号”唯一标识网络通讯中的一个进程,“IP + 端口号”就称为socket.在TCP协议中,建立 ...