zoukankan      html  css  js  c++  java
  • 【从零单排】浅析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

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

    链接

  • 相关阅读:
    NKOI 1363 (基础二分)
    POJ 1321 棋盘问题(dfs八皇后变形)
    UVA 1368 DNA(模拟+贪心)
    暴力(解数阵)
    A Linear Algebra Problem(唯一性的判定)
    hdu 1565 方格取数(1)
    hdu 1074 Doing Homework
    hdu 1233 还是畅通工程
    hdu 1232 畅通工程
    hdu 1213 How Many Tables
  • 原文地址:https://www.cnblogs.com/maxstack/p/7891827.html
Copyright © 2011-2022 走看看