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

相关文章
|
12天前
|
Java
判断不为空和不为空串的方法java
判断不为空和不为空串的方法java
|
1天前
|
Java 程序员 API
Java 8新特性之Lambda表达式与Stream API的深度解析
【5月更文挑战第12天】本文将深入探讨Java 8中的两个重要新特性:Lambda表达式和Stream API。我们将从基本概念入手,逐步深入到实际应用场景,帮助读者更好地理解和掌握这两个新特性,提高Java编程效率。
11 2
|
3天前
|
XML JavaScript Java
详解Java解析XML的四种方法
详解Java解析XML的四种方法
|
3天前
|
存储 Java API
掌握8条方法设计规则,设计优雅健壮的Java方法
掌握8条方法设计规则,设计优雅健壮的Java方法
|
3天前
|
Java 编译器 开发者
Java一分钟之-继承:复用与扩展类的特性
【5月更文挑战第9天】本文探讨了Java中的继承机制,通过实例展示了如何使用`extends`创建子类继承父类的属性和方法。文章列举了常见问题和易错点,如构造器调用、方法覆盖、访问权限和类型转换,并提供了解决方案。建议深入理解继承原理,谨慎设计类结构,利用抽象类和接口以提高代码复用和扩展性。正确应用继承能构建更清晰、灵活的代码结构,提升面向对象设计能力。
9 0
|
3天前
|
Java C语言
详解java方法与递归
详解java方法与递归
10 3
|
4天前
|
SQL Java 数据库连接
JDBC Java标准库提供的一些api(类+方法) 统一各种数据库提供的api
JDBC Java标准库提供的一些api(类+方法) 统一各种数据库提供的api
9 0
|
4天前
|
Java
Java一分钟之-方法定义与调用基础
【5月更文挑战第8天】本文介绍了Java编程中的方法定义和调用,包括基本结构、常见问题和避免策略。方法定义涉及返回类型、参数列表和方法体,易错点有返回类型不匹配、参数错误和忘记返回值。在方法调用时,要注意参数传递、静态与非静态方法的区分,以及重载方法的调用。避免错误的策略包括明确返回类型、参数校验、理解值传递、区分静态和非静态方法以及合理利用重载。通过学习和实践,可以提升编写清晰、可维护代码的能力。
13 0
|
7天前
|
搜索推荐 Java Shell
8大Java排序方法(由简入繁),有代码详解和原理指导
8大Java排序方法(由简入繁),有代码详解和原理指导
31 0
|
8天前
|
安全 Java 程序员
Java 8新特性之Lambda表达式
【5月更文挑战第5天】 本文将介绍Java 8中的一个重要新特性——Lambda表达式。Lambda表达式是Java 8引入的一种简洁、易读的函数式编程语法,它允许我们将函数作为参数传递给方法,或者作为返回值。通过使用Lambda表达式,我们可以编写更简洁、更易读的代码,提高开发效率。