zoukankan      html  css  js  c++  java
  • Java学习笔记-方法引用

    方法引用(Method Reference)

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

     1 public class Person {
     2 
     3     public enum Sex {
     4         MALE, FEMALE
     5     }
     6 
     7     String name;
     8     LocalDate birthday;
     9     Sex gender;
    10     String emailAddress;
    11     int age;
    12 
    13     public int getAge() {
    14         return age;
    15     }
    16     
    17     public LocalDate getBirthday() {
    18         return birthday;
    19     }    
    20 
    21     public static int compareByAge(Person a, Person b) {
    22         return a.birthday.compareTo(b.birthday);
    23     }
    24

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

    1 Person[] rosterAsArray = roster.toArray(new Person[roster.size()]);
    2 
    3 class PersonAgeComparator implements Comparator<Person> {
    4     public int compare(Person a, Person b) {
    5         return a.getBirthday().compareTo(b.getBirthday());
    6     }
    7 }
    8         
    9 Arrays.sort(rosterAsArray, new PersonAgeComparator()); 

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

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

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

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

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

    1 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)引用实例方法

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

     1 class ComparisonProvider {
     2     public int compareByName(Person a, Person b) {
     3         return a.getName().compareTo(b.getName());
     4     }
     5         
     6     public int compareByAge(Person a, Person b) {
     7         return a.getBirthday().compareTo(b.getBirthday());
     8     }
     9 }
    10 ComparisonProvider myComparisonProvider = new ComparisonProvider();
    11 Arrays.sort(rosterAsArray, myComparisonProvider::compareByName); 

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

    以String为例:

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

    (4)引用构造函数

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

     1 public static <T, SOURCE extends Collection<T>, DEST extends Collection<T>>
     2     DEST transferElements(
     3         SOURCE sourceCollection,
     4         Supplier<DEST> collectionFactory) {
     5         
     6         DEST result = collectionFactory.get();
     7         for (T t : sourceCollection) {
     8             result.add(t);
     9         }
    10         return result;
    11

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

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

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

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

    总结

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

    参考

           Method references

  • 相关阅读:
    docker 操作命令
    cenos 下docker安装gitlab
    jenkins实现git钩子
    这大概是晚上最简单的翻牌效果了吧
    centos配置nginx
    putty操作指南
    阿里云centos配置jenkins
    阿里云centos配置tomcat
    利用canvas生成二维码
    生成二维码
  • 原文地址:https://www.cnblogs.com/shuimuzhushui/p/8261205.html
Copyright © 2011-2022 走看看