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. 生产者&消费者.py

    1.最简单的 --生产者消费者 send.py# !/usr/bin/env python3.5# -*- coding:utf-8 -*-# __author__ == 'LuoTianShuai' ...

  2. python中无法被转化为set的list[list组成的list]

    arr = [[a],[b]] set(arr) output: Traceback (most recent call last): File "<stdin>", ...

  3. Jmeter工具之上传图片,上传音频文件接口

    https://www.jianshu.com/p/f23f7fe20bf3 互联网时代的来临,不同手机上安装的APP,还是PC端的应用软件或多或多都会涉及到图片的上传,那么在Jmeter工具如何模拟 ...

  4. 老铁,告别postman,用pycharm来调接口,顺便把接口脚本也写了

    最近,一位同事在用postman调涉及到依赖的接口的时候 postman设置了环境变量,但是老是获取不到依赖接口返回的值,至于的啥原因呢,@#¥%……&*()! 其实,用pycharm一样可以 ...

  5. [CTSC2012]熟悉的文章(后缀自动机+动态规划)

    题目描述 阿米巴是小强的好朋友. 在小强眼中,阿米巴是一个作文成绩很高的文艺青年.为了获取考试作文的真谛,小强向阿米巴求教.阿米巴给小强展示了几篇作文,小强觉得这些文章怎么看怎么觉得熟悉,仿佛是某些范 ...

  6. poj3190 Stall Reservations

    我一开始想用线段树,但是发现还要记录每头cow所在的棚...... 无奈之下选择正解:贪心. 用priority_queue来维护所有牛棚中结束时间最早的那个牛棚,即可得出答案. 注意代码实现的细节. ...

  7. @Async的简单用法总结

    前言: 在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的:但是在处理与第三方系统交互的时 候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在Spring 3 ...

  8. Xml二(解析思想)、

    XML解析: * 解析xml可以做: * 如果xml作为配置文件:读取 * 如果xml作为传输文件:写,读 * xml解析思想: * DOM:将文档加载进内存,形成一颗dom树(document对象) ...

  9. (线性dp,最大连续和)Max Sequence

    Max Sequence Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 18511   Accepted: 7743 Des ...

  10. 使用text-align:justify,让内容两端对齐,兼容IE及主流浏览器的方法

    如果不喜欢看分析过程,可以跳到最后看最终兼容方案 史前方法: 以前实现两端对齐是这样的: <p class="box1">密  码</p> <p cl ...