浅析Java 8新特性Method Reference

Posted MaxStack

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅析Java 8新特性Method Reference相关的知识,希望对你有一定的参考价值。

什么是方法引用

我们知道了什么是Lambda Expression以及如何使用,那么,Method References又是什么呢?Oracle Java Docs中这样说:

They are compact, easy-to-read lambda expressions for methods that already have a name.

也就是说,它是把已经定义好的有名字的方法,当作Lambda Expression来使用。

它的常用语法为:className::methodName

理解方法引用

通过一个例子来看:有一个数组,里面放了一堆Person对象,现在想要对它根据生日进行排序。

Person类

public class Person {
    LocalDate birthday;
    public Calendar getBirthday() {
        return birthday;
    }    
    public static int compareByAge(Person a, Person b) {
        return a.birthday.compareTo(b.birthday);
    }
}

常规写法

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());

Lambda Expression写法1:手动比较两个Date

Arrays.sort(rosterAsArray,
    (Person a, Person b) -> {
        return a.getBirthday().compareTo(b.getBirthday());
    }
);

分析这个Lambda Expression

  • 首先,它overwrite了Comparator.compare()方法。
  • 然后,看一下compare()的参数:int compare(T o1, T o2),它的输入是两个类型一致的对象,返回值为int型。对应到表达式:
  • 左边:(Person a, Person b),定义了输入参数,两个Person类型的对象。
  • 右边:a.getBirthday().compareTo(b.getBirthday()),定义了输出参数,类型为int。

我们发现,对于右边,不一定要调用Date.compareTo()方法,其他任意自定义的方法都可以,只需要满足输入输出参数一致即可。
正好,Person类里面已经定义了一个compareByAge()方法可以直接拿过来替换。于是,可以改成这样:

Lambda Expression写法2:调用已经定义好的方法

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

再对其分析,可以发现,左边(Person a, Person b)其实是冗余信息,因为右边Person.compareByAge(a, b)方法已经定义好了输入输出。

所以,上面的代码可以简化如下:

Method Reference写法

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

几种类型

Method Reference有以下几种类型:

  • 引用静态方法: ClassName::staticMethodName
  • 引用构造方法: ClassName::new
  • 引用某个实例上的实例方法应用: instanceReference::instanceMethodName
  • 引用某个类型上的实例方法引用: ClassName::instanceMethodName

在使用“某个类型上的实例方法引用”时,需要传入实例化参数;而在使用“某个实例上的实例方法应用”时,因为已经实例化过了所以并不需要。

链接

以上是关于浅析Java 8新特性Method Reference的主要内容,如果未能解决你的问题,请参考以下文章

浅谈Java 8中的方法引用(Method References)

java7新特性之Simplified varargs method invocation

浅析Java 8新功能Optional

浅析chrome新特性之默认使用HTTPS,追溯源头至HSTS

重学Java 8新特性 | 第2讲——Java 8新特性简介

浅析Java源码之ArrayList