Java8新特性之二:方法引用

简介: Java8新特性之二:方法引用上一节介绍了Java8新特性中的Lambda表达式,本小节继续讲解Java8的新特性之二:方法引用。方法引用其实也离不开Lambda表达式。1、方法引用的使用场景  我们用Lambda表达式来实现匿名方法。

Java8新特性之二:方法引用
上一节介绍了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类,如下所示:

复制代码
1 @Data
2 public class Person {
3
4 private String name;
5
6 private Integer age;
7
8 public static int compareByAge(Person a, Person b) {
9 return a.age.compareTo(b.age);
10 }
11 }
复制代码
  现假设,一个部门有30人,把他们存放在一个数组中,并按年龄排序,通常我们可以自己写一个比较器,代码如下:

复制代码
1 Person[] rosterAsArray = new Person[30];
2 // 添加数组元素省略
3
4 class PersonAgeComparator implements Comparator {
5 public int compare(Person a, Person b) {
6 return a.getBirthday().compareTo(b.getBirthday());
7 }
8 }
9
10 Arrays.sort(rosterAsArray, new PersonAgeComparator());
复制代码
  Arrays.sort的声明为:public static void sort(T[] a, Comparator<? super T> c),比较器参数Comparator为一个函数式接口,利用上一节Lambda表达式所学知识,可以改写为以下代码:

1 Person[] rosterAsArray = new Person[30];
2 // 添加数组元素省略
3
4 Arrays.sort(rosterAsArray, (a,b) -> a.getAge().compareTo(b.getAge()));
  然而,你会发现,Perdon类中已经有了一个静态方法的比较器:compareByAge,因此,我们改用Person类已经提供的比较器:

1 Person[] rosterAsArray = new Person[30];
2 // 添加数组元素省略
3
4 Arrays.sort(rosterAsArray, (a,b) -> Person.compareByAge(a,b));
  以上代码,因为Lambda表达式调用了一个已经存在的静态方法,根据我们第2节表格中的语法,上面的代码可以最终改写成静态方法引用:

1 Person[] rosterAsArray = new Person[30];
2 // 添加数组元素省略
3
4 Arrays.sort(rosterAsArray, Person::compareByAge);
  下面这个例子更简单:

复制代码
1 public class Test {
2 public static void main(String[] args) {
3 List list = Arrays.asList(82,22,34,50,9);
4 list.sort(Integer::compare);
5 System.out.println(list);
6 }
7 }
复制代码
  对一个Integer列表进行排序,因为Integer中已经存在静态的比较方法compare(),因此可以直接用静态方法引用的方式来调用 ,运行结果为:

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

复制代码
1 @Data
2 class User {
3
4 private String name;
5 private Integer age;
6
7 public User(String name, Integer age) {
8 this.name = name;
9 this.age = age;
10 }
11 }
12
13 public class TestInstanceReference {
14
15 public static void main(String[] args) {
16
17 TestInstanceReference test = new TestInstanceReference();
18 User user = new User("欧阳峰",32);
19 Supplier supplier = () -> user.getName();
20 System.out.println("Lambda表达式输出结果:" + supplier.get());
21
22 Supplier supplier2 = user::getName;
23 System.out.println("实例方法引用输出结果:" + supplier2.get());
24 }
25 }
复制代码
  输出结果:

Lambda表达式输出结果:欧阳峰
实例方法引用输出结果:欧阳峰
3.3 对象方法引用
  若Lambda参数列表中的第一个参数是实例方法的参数调用者,而第二个参数是实例方法的参数时,可以使用对象方法引用。

String的equals()方法:

复制代码
1 public boolean equals(Object anObject) {
2 if (this == anObject) {
3 return true;
4 }
5 if (anObject instanceof String) {
6 String anotherString = (String)anObject;
7 int n = value.length;
8 if (n == anotherString.value.length) {
9 char v1[] = value;
10 char v2[] = anotherString.value;
11 int i = 0;
12 while (n-- != 0) {
13 if (v1[i] != v2[i])
14 return false;
15 i++;
16 }
17 return true;
18 }
19 }
20 return false;
21 }
复制代码
复制代码
1 public static void main(String[] args) {
2
3 BiPredicate bp = (x, y) -> x.equals(y);
4 BiPredicate bp1 = String::equals;
5
6 boolean test = bp1.test("xy", "xx");
7 System.out.println(test);
8 }
复制代码
  BiPredicate的test()方法接受两个参数,x和y,具体实现为x.equals(y),满足Lambda参数列表中的第一个参数是实例方法的参数调用者,而第二个参数是实例方法的参数,因此可以使用对象方法引用。

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

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

1 Supplier> userSupplier = () -> new ArrayList<>();
2 List user = userSupplier.get();
3
4 Supplier> userSupplier2 = ArrayList::new; // 构造方法引用写法
5 List user2 = userSupplier.get();
  至此,方法引用讲完了,下一章节将讲解Stream API。

  原文地址https://www.cnblogs.com/wuhenzhidu/p/10727065.html

相关文章
|
15天前
|
安全 Java 数据安全/隐私保护
|
15天前
|
搜索推荐 Java
Java的面向对象特性主要包括封装、继承和多态
【4月更文挑战第5天】Java的面向对象特性主要包括封装、继承和多态
13 3
|
9天前
|
Java
Java中ReentrantLock中tryLock()方法加锁分析
Java中ReentrantLock中tryLock()方法加锁分析
11 0
|
1天前
|
机器学习/深度学习 Java API
Java8中的新特性
Java8中的新特性
|
1天前
|
Java
Java接口中可以定义哪些方法?
【4月更文挑战第13天】
5 0
Java接口中可以定义哪些方法?
|
4天前
|
分布式计算 Java API
Java 8新特性之Lambda表达式与Stream API
【4月更文挑战第16天】本文将介绍Java 8中的两个重要新特性:Lambda表达式和Stream API。Lambda表达式是Java 8中引入的一种新的编程语法,它允许我们将函数作为参数传递给其他方法,从而使代码更加简洁、易读。Stream API是Java 8中引入的一种新的数据处理方式,它允许我们以声明式的方式处理数据,从而使代码更加简洁、高效。本文将通过实例代码详细讲解这两个新特性的使用方法和优势。
|
7天前
|
Java Shell
Java 21颠覆传统:未命名类与实例Main方法的编码变革
Java 21颠覆传统:未命名类与实例Main方法的编码变革
10 0
|
9天前
|
Java
Java中关于ConditionObject的signal()方法的分析
Java中关于ConditionObject的signal()方法的分析
21 4
|
9天前
|
安全 Java
append在Java中是哪个类下的方法
append在Java中是哪个类下的方法
21 9
|
10天前
|
Java API 开发者
Java 8新特性之函数式编程实战
【4月更文挑战第9天】本文将深入探讨Java 8的新特性之一——函数式编程,通过实例演示如何运用Lambda表达式、Stream API等技术,提高代码的简洁性和执行效率。