Method References

Background or Issue:

  It's no sence to invoke an existing method by a lambda expression,so do it with method's name.

 

Introduction with Example

 1 public class MethodReferencesTest {
 2 
 3   // The method transferElements copies elements from one
 4   // collection to another
 5 
 6   public static <T, SOURCE extends Collection<T>, DEST extends Collection<T>>
 7     DEST transferElements(
 8         SOURCE sourceCollection,
 9         Supplier<DEST> collectionFactory){
10 
11     DEST result = collectionFactory.get();
12     for (T t : sourceCollection) {
13       result.add(t);
14     }
15     return result;
16   }
17 
18   public static void main(String[] args) {
19 
20     List<Person> roster = Person.createRoster();
21 
22     for (Person person : roster) {
23       person.printPerson();
24     }
25 
26     Person[] rosterAsArray = roster.toArray(new Person[roster.size()]);
27 
28 
29     class PersonAgeComparator implements Comparator <Person>{
30       @Override
31       public int compare(Person o1, Person o2) {
32         return o1.getBirthday().compareTo(o2.getBirthday());
33       }
34     }
35 
36     // Without method reference
37     Arrays.sort(rosterAsArray, new PersonAgeComparator());
38 
39     // With lambda expression
40     // Notice that the interface Comparator is a functional interface.
41     // Therefore, use a lambda expression instead of defining
42     // and then creating a new instance of a class that implements Comparator
43     Arrays.sort(rosterAsArray,
44         (a, b) -> a.getBirthday().compareTo(b.getBirthday()));
45 
46     // Invokes an existing method with lambda expression
47     // This method to compare the birth dates of two Person instances
48     // already exists as Person.compareByAge. Invoke this method instead
49     // in the body of the lambda expression
50     Arrays.sort(rosterAsArray,
51         (a, b) -> Person.compareByAge(a, b));
52 
53     // 1. Reference to a Static Method
54     Arrays.sort(rosterAsArray, Person::compareByAge);
55 
56     // 2. Reference to an instance method of a particular object
57     class ComparisionProvider{
58       public int compareByName(Person a, Person b){
59         return a.getName().compareTo(b.getName());
60       }
61 
62       public int compareByAge(Person a, Person b){
63         return a.getBirthday().compareTo(b.getBirthday());
64       }
65     }
66     ComparisionProvider myComparisionProvider = new ComparisionProvider();
67     Arrays.sort(rosterAsArray, myComparisionProvider::compareByAge);
68 
69     // 3. Reference to an instance method
70     // of an arbitrary object of a particular type
71     String[] stringArray = { "Barbara", "James", "Mary", "John",
72         "Patricia", "Robert", "Michael", "Linda" };
73     Arrays.sort(stringArray, String::compareToIgnoreCase);
74 
75     // the equivalent lambda expression for the method inference
76     // String::compareToIgnoreCase
77     Arrays.sort(stringArray, (a, b) -> a.compareToIgnoreCase(b));
78 
79     // 4. Reference to a Constructor
80     // You can reference a constructor in the same way
81     // as a static method by using the name new.
82     Set<Person> rosterSetLambda =
83         transferElements(roster, () -> new HashSet<>());
84 
85     // use a constructor reference in place of the lambda expression
86     // The Java compiler infers that you want to create a HashSet
87     // collection that contains elements of type Person
88     Set<Person> rosterSet = transferElements(
89         roster, HashSet::new);
90 
91     System.out.println("Printing rosterSet: ");
92     rosterSet.stream().forEach(p -> p.printPerson());
93   }
94 }
View Code

 

posted @ 2020-08-11 09:41  deep-thinking  阅读(101)  评论(0编辑  收藏  举报