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. Get The Treasury HDU - 3642(体积扫描线)

    给出n个立方体,要你求这些立方体至少被覆盖三次的部分. 先把这个立方体的信息存在来,发现Z的范围不大,z范围是是[-500,500],所以我们可以先离散化,然后枚举Z, 然后对于每一段Z的区域内,在当 ...

  2. bzoj3756pty的字符串(后缀自动机+计数)

    题目描述 题解 我们可以先对trie树建出广义SAM,然后维护一下right集合大小(注意right集合在广义SAM上的维护方式). 然后把匹配穿往广义SAM上匹配,假设现在匹配到了x节点,那么x的所 ...

  3. layer 弹出层

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  4. hdu 2159 FATE (二维完全背包)

    Problem Description 最近xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务.久而久之xhd开始对杀怪产生的厌恶感,但又不得不通过杀怪来升完这最后一级.现 ...

  5. 在JSON中遇到的一些坑

    今天在进行压测的时候,由于需要使用到json进行传参,并且需要在JMeter中加入少量的JSON,由于JSON在java中呈现键值对的形式,并且需要使用到“”来修饰,导致只能使用\进行转义,在发送请求 ...

  6. CodeFroces-- 511div2 C. Enlarge GCD

    题目链接:C. Enlarge GCD 给你一个序列 删除一些数看可以让他们之间的gcd变大如果可以输出删除数量最小的个数 先求出共同 gcd 然后除去 找出出现最多的质数 然后减去就可以了 #inc ...

  7. ocr智能图文识别 tess4j 图文,验证码识别

    最近写爬虫采集数据,遇到网站登录需要验证码校验,想了想有两种解决办法 1,利用htmlunit,将验证码输入到swing中,并弹出一个输入框,手动输入验证码,这种实现方式,如果网站需要登录一次可以使用 ...

  8. [luogu3709][大爷的字符串题]

    题目链接 题意 一天做到两道这种题目描述如此神仙的题也是够了.真锻炼语文能力. 题目的意思其实就是,给你一个序列,然后每次询问一个区间.使得尽量按照严格上升的顺序从这个区间内取数.如果当前取得数字小于 ...

  9. 第十八篇-Spinner下拉列表的使用

    效果图 MainActivity.java package com.example.aimee.spinnertest; import android.support.v7.app.AppCompat ...

  10. C++ Exception机制

    C++异常机制的执行顺序. 在构造函数内抛出异常 /* * ExceptClass.h * * Created on: 2018年1月2日 * Author: jacket */ #ifndef EX ...