博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java8新特性之二:方法引用
阅读量:6293 次
发布时间:2019-06-22

本文共 4451 字,大约阅读时间需要 14 分钟。

  上一节介绍了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 <T> 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

你可能感兴趣的文章
Storm中的Worker
查看>>
dangdang.ddframe.job中页面修改表达式后进行检查
查看>>
Web基础架构:负载均衡和LVS
查看>>
Linux下c/c++相对路径动态库的生成与使用
查看>>
SHELL实现跳板机,只允许用户执行少量允许的命令
查看>>
SpringBoot 整合Redis
查看>>
2014上半年大片早知道
查看>>
Android 6.0指纹识别App开发案例
查看>>
正文提取算法
查看>>
轻松学PHP
查看>>
Linux中的网络监控命令
查看>>
this的用法
查看>>
windows下安装redis
查看>>
CentOS7 yum 安装git
查看>>
启动日志中频繁出现以下信息
查看>>
httpd – 对Apache的DFOREGROUND感到困惑
查看>>
分布式锁的一点理解
查看>>
idea的maven项目,install下载重复下载本地库中已有的jar包,而且下载后jar包都是lastupdated问题...
查看>>
2019测试指南-web应用程序安全测试(二)指纹Web服务器
查看>>
树莓派3链接wifi
查看>>