方法引用(Method Reference)

上一篇中记录了Lambda表达式,其可以创建匿名方法。当Lambda表达式只是调用一个存在的方法时,可以采用方法引用(JDK8具有的特性)。如下:

 public class Person {

     public enum Sex {
MALE, FEMALE
} String name;
LocalDate birthday;
Sex gender;
String emailAddress;
int age; public int getAge() {
return age;
} public LocalDate getBirthday() {
return birthday;
} public static int compareByAge(Person a, Person b) {
return a.birthday.compareTo(b.birthday);
}

假设需要对一组人员按年龄进行排序,可以采用下边的方式,将人员数组与实现的比较器,传递给Array.sort方法:

 Person[] rosterAsArray = roster.toArray(new Person[roster.size()]);

 class PersonAgeComparator implements Comparator<Person> {
public int compare(Person a, Person b) {
return a.getBirthday().compareTo(b.getBirthday());
}
} Arrays.sort(rosterAsArray, new PersonAgeComparator()); 

当然,可以将PersonAgeComparator的实现采用Lambda表达式,如下:

  Arrays.sort(rosterAsArray, (a,b) -> a.birthday.compareTo(b.birthday)); 

Person类中已经包含根据年龄的比较compareByAge,只需要在Lambda表达式体中直接调用即可

 Arrays.sort( rosterAsArray, (a,b) -> Person.compareByAge(a,b)); 

由于Lambda表达式调用一个已经存在的方法,可以使用方法引用代替Lambda表达式,如下:

 Arrays.sort(rosterAsArray, Person::compareByAge); 

其中 ,Person::compareByAge 与 (a, b) -> Person.compareByAge(a, b)是等价的。(1)其参数拷贝于Comparator<Person>.compare,即 (Person, Person);(2)body将调用Person.compareByAge。

方法引用类别

有4种方法引用,如下:

  • 引用静态方法,如 ContainingClass::staticMethodName;
  • 引用实例方法,如 containingObject::instanceMethodName;
  • 引用特殊类型对象的方法,如 ContainingType::methodName;
  • 引用构造函数,如 ClassName::new。

(1)引用静态方法

上文中的例子即为静态方法引用。

(2)引用实例方法

即通过类的实例引用方法,如下:

 class ComparisonProvider {
public int compareByName(Person a, Person b) {
return a.getName().compareTo(b.getName());
} public int compareByAge(Person a, Person b) {
return a.getBirthday().compareTo(b.getBirthday());
}
}
ComparisonProvider myComparisonProvider = new ComparisonProvider();
Arrays.sort(rosterAsArray, myComparisonProvider::compareByName); 

(3)引用特殊类型对象的方法

以String为例:

 String[] stringArray = { "Barbara", "James", "Mary", "John",
"Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase); 

(4)引用构造函数

假设transferElements实现从一个集合到另一个集合拷贝元素,如下:

 public static <T, SOURCE extends Collection<T>, DEST extends Collection<T>>
DEST transferElements(
SOURCE sourceCollection,
Supplier<DEST> collectionFactory) { DEST result = collectionFactory.get();
for (T t : sourceCollection) {
result.add(t);
}
return result;

其中Supplier包含一个get方法,只返回一个空的集合对象,并且不需要任何参数,可以使用Lambda表达式实现,如下:

 Set<Person> rosterSetLambda =
transferElements(roster, () -> { return new HashSet<>(); }); 

此时可以采用引用构造函数的方法,如下:

Set<Person> rosterSet = transferElements(roster, HashSet::new);
//或
Set<Person> rosterSet = transferElements(roster, HashSet<Person>::new); 

总结

  • 对于Lambda表达式,当只是调用一个已存在的方法时,可以采用方法引用的方式实现,编译器会自行翻译

参考

Method references

Java学习笔记-方法引用的更多相关文章

  1. JAVA学习笔记--方法中的参数调用是引用调用or值调用

    文献来源:<JAVA核心技术卷Ⅰ>,第4章第5节 (没有相关书籍的可看传送门) ps:测试demo因为偷懒,用的是String对象 结论:Java使用的是对象的值引用.即将任何对象所在内存 ...

  2. java学习笔记 --- 方法

    一.方法  (1)方法:就是完成特定功能的代码块.   注意:在很多语言里面有函数的定义,而在Java中,函数被称为方法.  (2)格式:   修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 ...

  3. Java学习笔记day03_引用数据类型

    1.引用数据类型 步骤: 1. 导包   2. 创建引用类型变量 类型 变量名 = new 类型名();   3. 使用数据类型的功能 变量名.功能名(); 如Scanner类: import jav ...

  4. 0030 Java学习笔记-面向对象-垃圾回收、(强、软、弱、虚)引用

    垃圾回收特点 垃圾:程序运行过程中,会为对象.数组等分配内存,运行过程中或结束后,这些对象可能就没用了,没有变量再指向它们,这时候,它们就成了垃圾,等着垃圾回收程序的回收再利用 Java的垃圾回收机制 ...

  5. Java学习笔记之---方法和数组

    Java学习笔记之---方法与数组 (一)方法 (1)什么是方法? 方法是解决一类问题的步骤的有序组合 方法包含于类或对象中 方法在程序中被创建,在其他地方被引用 (2)方法的优点 使程序变得更简短而 ...

  6. java学习笔记5--类的方法

    接着前面的学习: java学习笔记4--类与对象的基本概念(2) java学习笔记3--类与对象的基本概念(1) java学习笔记2--数据类型.数组 java学习笔记1--开发环境平台总结 本文地址 ...

  7. Java学习笔记(04)

    Java学习笔记(04) 如有不对或不足的地方,请给出建议,谢谢! 一.对象 面向对象的核心:找合适的对象做合适的事情 面向对象的编程思想:尽可能的用计算机语言来描述现实生活中的事物 面向对象:侧重于 ...

  8. 0032 Java学习笔记-类加载机制-初步

    JVM虚拟机 Java虚拟机有自己完善的硬件架构(处理器.堆栈.寄存器等)和指令系统 Java虚拟机是一种能运行Java bytecode的虚拟机 JVM并非专属于Java语言,只要生成的编译文件能匹 ...

  9. 0028 Java学习笔记-面向对象-Lambda表达式

    匿名内部类与Lambda表达式示例 下面代码来源于:0027 Java学习笔记-面向对象-(非静态.静态.局部.匿名)内部类 package testpack; public class Test1{ ...

随机推荐

  1. Struts2数据验证与使用Java代码进行数据验证

    Struts2数据验证 使用Java代码进行数据验证 重写ActionSupport的validate()方法 对Action类的中所有请求处理方法都会进行验证! 对Action类的数据属性进行检查, ...

  2. Android ImageView 获取图片信息后进行比较

    ImageView a=(ImageView)findViewById(R.id.imageView2); //获取当前图片ConstantState类对象 Drawable.ConstantStat ...

  3. 百度jQuery库

    <script src="http://apps.bdimg.com/libs/jquery/1.11.1/jquery.js"></script>

  4. andriod的apk文件相关的编译反编译工具

    1.smali-1.2.6.jar 用途:.smali文件 转成 classes.dex文件 说明:.smali文件,类似于.class文件,可以用普通文本编辑器查看和修改. 用法举例:命令行:jav ...

  5. Nagle's algorithm

    w41字节的数据包只有1字节的可用信息.以减少数据包发送量来提高TCP/IP网络性能. https://en.wikipedia.org/wiki/Nagle's_algorithm https:// ...

  6. Fat URLs Client Identification

    w在每个URL后面都附加一个用户特有的标识码. HTTP The Definitive Guide Some web sites keep track of user identity by gene ...

  7. Windows中压缩版的MySQL的安装、配置

    本次笔记是根据mysql-8.0.13-winx64版本编写: 1.将下载的压缩包解压到自己想放的目录 2.右键计算机 -> 属性 -> 高级系统设置 -> 环境变量 -> 系 ...

  8. C#、devExpress 的 给bandedGrid加菜单功能 :复制、粘贴的例子(转)

    C#.devExpress 的 给bandedGrid加菜单功能 :复制.粘贴的例子 CopyFromGrid PasteToGrid PasteNewRowsToGrid private void ...

  9. GITLAB服务基础

    1.GITLAB介绍 一个基于GIT的源码托管解决方案基于Ruby on rails开发集成了nginx postgreSQL redis sidekiq等组件 2. 资源 官网:https://ab ...

  10. 【numpy】

    ndarray在某个维度上堆叠,np.stack() np.hstack() np.vstack() https://blog.csdn.net/csdn15698845876/article/det ...