上一节介绍了Java8新特性中的Lambda表达式,本小节继续讲解Java8的新特性之二:方法引用。方法引用其实也离不开Lambda表达式。

1、方法引用的使用场景

  我们用Lambda表达式来实现匿名方法。但有些情况下,我们用Lambda表达式仅仅是调用一些已经存在的方法,除了调用动作外,没有其他任何多余的动作,在这种情况下,我们倾向于通过方法名来调用它,而Lambda表达式可以帮助我们实现这一要求,它使得Lambda在调用那些已经拥有方法名的方法的代码更简洁、更容易理解。方法引用可以理解为Lambda表达式的另外一种表现形式。

2、方法引用的分类

类型 语法 对应的Lambda表达式
静态方法引用 类名::staticMethod (args) -> 类名.staticMethod(args)
实例方法引用 inst::instMethod (args) -> inst.instMethod(args)
对象方法引用 类名::instMethod (inst,args) -> 类名.instMethod(args)
构建方法引用 类名::new (args) -> new 类名(args)

3、方法引用举例

3.1 静态方法引用

  有一个Person类,如下所示:

 @Data
public class Person { private String name; private Integer age; public static int compareByAge(Person a, Person b) {
return a.age.compareTo(b.age);
}
}

  现假设,一个部门有30人,把他们存放在一个数组中,并按年龄排序,通常我们可以自己写一个比较器,代码如下:

 Person[] rosterAsArray = new Person[30];
// 添加数组元素省略 class PersonAgeComparator implements Comparator<Person> {
public int compare(Person a, Person b) {
return a.getBirthday().compareTo(b.getBirthday());
}
} Arrays.sort(rosterAsArray, new PersonAgeComparator());

  Arrays.sort的声明为:public static <T> void sort(T[] a, Comparator<? super T> c),比较器参数Comparator为一个函数式接口,利用上一节Lambda表达式所学知识,可以改写为以下代码:

 Person[] rosterAsArray = new Person[30];
// 添加数组元素省略 Arrays.sort(rosterAsArray, (a,b) -> a.getAge().compareTo(b.getAge()));

  然而,你会发现,Perdon类中已经有了一个静态方法的比较器:compareByAge,因此,我们改用Person类已经提供的比较器:

 Person[] rosterAsArray = new Person[30];
// 添加数组元素省略 Arrays.sort(rosterAsArray, (a,b) -> Person.compareByAge(a,b));

  以上代码,因为Lambda表达式调用了一个已经存在的静态方法,根据我们第2节表格中的语法,上面的代码可以最终改写成静态方法引用:

 Person[] rosterAsArray = new Person[30];
// 添加数组元素省略 Arrays.sort(rosterAsArray, Person::compareByAge);

  下面这个例子更简单:

 public class Test {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(82,22,34,50,9);
list.sort(Integer::compare);
System.out.println(list);
}
}

  对一个Integer列表进行排序,因为Integer中已经存在静态的比较方法compare(),因此可以直接用静态方法引用的方式来调用 ,运行结果为:

[9, 22, 34, 50, 82]

3.2 实例方法引用

  实例方法引用,顾名思义就是调用已经存在的实例的方法,与静态方法引用不同的是类要先实例化,静态方法引用类无需实例化,直接用类名去调用。

 @Data
class User { private String name;
private Integer age; public User(String name, Integer age) {
this.name = name;
this.age = age;
}
} public class TestInstanceReference { public static void main(String[] args) { TestInstanceReference test = new TestInstanceReference();
User user = new User("欧阳峰",32);
Supplier<String> supplier = () -> user.getName();
System.out.println("Lambda表达式输出结果:" + supplier.get()); Supplier<String> supplier2 = user::getName;
System.out.println("实例方法引用输出结果:" + supplier2.get());
}
}

  输出结果:

Lambda表达式输出结果:欧阳峰
实例方法引用输出结果:欧阳峰

3.3 对象方法引用

  若Lambda参数列表中的第一个参数是实例方法的参数调用者,而第二个参数是实例方法的参数时,可以使用对象方法引用。

String的equals()方法:

 public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
 public static void main(String[] args) {

    BiPredicate<String,String> bp = (x, y) -> x.equals(y);
BiPredicate<String,String> bp1 = String::equals; boolean test = bp1.test("xy", "xx");
System.out.println(test);
}

  BiPredicate的test()方法接受两个参数,x和y,具体实现为x.equals(y),满足Lambda参数列表中的第一个参数是实例方法的参数调用者,而第二个参数是实例方法的参数,因此可以使用对象方法引用。

3.4 构造方法引用

  注意:需要调用的构造器的参数列表要与函数式接口中抽象方法的参数列表保持一致。

  如:要获取一个空的User列表:

 Supplier<List<User>> userSupplier = () -> new ArrayList<>();
List<User> user = userSupplier.get(); Supplier<List<User>> userSupplier2 = ArrayList<User>::new; // 构造方法引用写法
List<User> user2 = userSupplier.get();

  至此,方法引用讲完了,下一章节将讲解Stream API。

  

Java8新特性之二:方法引用的更多相关文章

  1. Java8新特性系列-默认方法

    Java8 Interface Default and Static Methods 原文连接:Java8新特性系列-默认方法 – 微爱博客 在 Java 8 之前,接口只能有公共抽象方法. 如果不强 ...

  2. 乐字节-Java8新特性-接口默认方法

    总概 JAVA8 已经发布很久,而且毫无疑问,java8是自java5(2004年发布)之后的最重要的版本.其中包括语言.编译器.库.工具和JVM等诸多方面的新特性. Java8 新特性列表如下: 接 ...

  3. java8新特性(二)_lambda表达式

    最近一直找java8相关新特性的文章,发现都太没有一个连贯性,毕竟大家写博客肯定都有自己的侧重点,这里找到一本书,专门介绍java8新特性的,感觉大家可以看看<写给大忙人看的JavaSE8> ...

  4. 乐字节-Java8新特性-接口默认方法之Stream流(下)

    接上一篇:<Java8新特性之stream>,下面继续接着讲Stream 5.流的中间操作 常见的流的中间操作,归为以下三大类:筛选和切片流操作.元素映射操作.元素排序操作: 操作 描述 ...

  5. Java8新特性——StreamAPI(二)

    1. 收集器简介 收集器用来将经过筛选.映射的流进行最后的整理,可以使得最后的结果以不同的形式展现. collect方法即为收集器,它接收Collector接口的实现作为具体收集器的收集方法. Col ...

  6. JAVA 8 主要新特性 ----------------(五)Lambda方法引用与构造器引用

    一.Lambda方法引用 当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!(实现抽象方法的参数列表,必须与方法引用方法的参数列表保持一致!) 方法引用: 使用操作符 “::” 将 ...

  7. Java8新特性(二)——强大的Stream API

    一.强大的Stream API 除了Lambda表达式外,Java8另外一项重大更新便是位于java.util.stream.*下的Stream API Stream 是 Java8 中处理集合的关键 ...

  8. Java8新特性——接口默认方法

    Java 8 新增了接口的默认方法. 简单说,默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法. 我们只需在方法名前面加个default关键字即可实现默认方法. 为什么要有这个特性? 首先 ...

  9. Java8新特性(二)之函数式接口

    .subTitle { background: rgba(51, 153, 0, 0.66); border-bottom: 1px solid rgba(0, 102, 0, 1); border- ...

随机推荐

  1. 单片机开发——02工欲善其事必先利其器(Proteus软件安装破解)

    在单片机开发工程中,博主经常通过模拟软件Proteus进行模拟仿真,将编译生成的"HEX"文件下载在单片机芯片中,然后进行后期的debug工作,当模拟仿真完成之后,进行硬件测试部分 ...

  2. 洛谷 P1041 错解

    P1041 传染病控制 题目背景 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的蔓延.不幸的是,由于人们尚未完全认识这种传染 ...

  3. .NET开发微信小程序-上传图片到服务器

    1.上传图片分为几种: a:上传图片到本地(永久保存) b:上传图片到本地(临时保存) c:上传图片到服务器 a和b在小程序的api文档里面有.直接说C:上传图片到服务器 前端代码: /* 上传图片到 ...

  4. Global一点小经验

    Global: Global.asax 文件,有时候叫做 ASP.NET 应用程序文件,提供了一种在一个中心位置响应应用程序级或模块级事件的方法,他位于应用程序根目录下. 这个 Global.asax ...

  5. IntelliJ IDEA maven 构建简单springmvc项目

    环境: apache-tomcat-8.5.15 jdk1.8.0_172 IDEA 建立一个maven-webapp项目:Create New Project 后点击next 然后next 可以选择 ...

  6. capwap学习笔记——初识capwap(三)(转)

    2.5.6 CAPWAP状态机详解 2.5.6.1 Start to Idle 这个状态变迁发生在设备初始化完成. ¢  WTP: 开启CAPWAP状态机. ¢  AC:  开启CAPWAP状态机. ...

  7. SQL*Loader FAQ

    SQL*Loader FAQ: Contents [hide]  1 What is SQL*Loader and what is it used for? 2 How does one use th ...

  8. 全国省市县区域信息最新数据库脚本(mysql版本)

    /*Navicat MySQL Data Transfer Source Server : localhostSource Server Version : 50717Source Host : lo ...

  9. 2. 网友对app后端写作系列文章的写作建议

    很感谢"app后端"qq群的网友,在发布消息后,就收到了大量网友的反馈 下面的建议会融入到写作当中: 1.还有,对版本升级很感兴趣,我们现在为了兼容旧版本,已经把工程代码搞的乱哄哄 ...

  10. Day1----Python学习之路笔记(1)

    学习路线 Day1 Day2 Day3 Day4 Day5 ...待续 一.了解开发语言 1.高级语言:Python,Java,C++,C#,PHP,JS,Go,Ruby,SQL,Swift,Perl ...