Java学习笔记-方法引用

2018-06-18 03:55:38来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

方法引用(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

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:DAY2-j打卡第二天2018-1-10

下一篇:JpaRepository QueryByExample方法使用详解