20 Nov 2015 
 Java 8 Method References 
   Method References 是什么?
 它是与 Lambda 表达式相关的一个功能. 它允许我们引用构造函数或者方法而无需执行. Method references 与 Lambda 非常相似, 因为它们都需要一个含有兼容的函数式接口的目标类型.
 Method Reference 的类型
 一共存在4种 Method Reference, 请参考表格:
    | 类型 |  例子 |  语法 |  
    | 1. 静态方法 |  ContainingClass::staticMethodName |  Class::staticMethodName |  
  | 2. 构造方法 |  ClassName::new |  ClassName::new |  
  | 3. 特定类型的任意对象的实例方法 |  ContainingType::methodName |  ContainingType::methodName |  
  | 4. 特定对象的实例方法 |  containingObject::instanceMethodName |  object::instanceMethodName |  
  
 1 . 静态方法
 public class ReferenceToStaticMethod {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        List  numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12,13,15,16);
        List primeNumbers = ReferenceToStaticMethod.findPrimeNumbers(numbers, ReferenceToStaticMethod::isPrime);
        System.out.println("Prime Numbers are "+primeNumbers);
    }
    public static boolean isPrime(int number) {
        if(number == 1 ){
            return false;
        }
        for (int i = 2; i < number; i++) {
            if (number % i == 0) {
                return false;
            }
        }
        return true;
    }
    public static List findPrimeNumbers(List list, Predicate predicate) {
        List sortedNumbers = new ArrayList();
        list.stream().filter((i) ->(predicate.test(i))).forEach((i) -> {
            sortedNumbers.add(i);
        });
        return sortedNumbers;
    }
}
     |   |    |  
    | 类 |  ReferenceToStaticMethod |  
  | 静态方法名 |  isPrime |  
  | Lambda 方式 |  List primeNumbers = ReferenceToStaticMethod.testPredicate(numbers, a -> ReferenceToStaticMethod.isPrime(a)); |  
  | Method Reference |  List primeNumbers = ReferenceToStaticMethod.testPredicate(numbers, ReferenceToStaticMethod::isPrime); |  
  
 2 . 构造方法
 public class ReferenceToConstructor {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
         List  numbers = Arrays.asList(4,9,16,25,36);
         List squaredNumbers = ReferenceToConstructor.findSquareRoot(numbers,Double::new);
         System.out.println("Square root of numbers = "+squaredNumbers);
    }
    private static List findSquareRoot(List list, Function<double,double> f){
        List result = new ArrayList();
        list.forEach(x -> result.add(f.apply(Math.sqrt(x))));
        return result;
    }
}
     |   |    |  
    | 类名 |  Double |  
  | new |  new |  
  | Lambda 方式 |  List squaredNumbers = ReferenceToConstructor.findSquareRoot(numbers, x -> new Double(x)); |  
  | Method Reference |  List squaredNumbers= ReferenceToConstructor.findSquareRoot(numbers,Double::new); |  
  
 3 . 特定类型的任意对象的实例方法
 public class ReferenceToInstanceMethodAOPT {
    /**
     * @param args the command line arguments
     */
     private static class Person {
            private final String name;
            private final int age;
            public Person(String name, int age) {
                this.name = name;
                this.age = age;
            }
            public String getName() {
                return name;
            }
            public int getAge() {
                return age;
            }
        }
    public static void main(String[] args) {
        // TODO code application logic here
        List persons = new ArrayList();
            persons.add(new Person("Albert", 80));
            persons.add(new Person("Ben", 15));
            persons.add(new Person("Charlote", 20));
            persons.add(new Person("Dean", 6));
            persons.add(new Person("Elaine", 17));
            List allAges = ReferenceToInstanceMethodAOPT.listAllAges(persons, Person::getAge);
            System.out.println("Printing out all ages \n"+allAges);
    }
    private static List listAllAges(List person, Function<person, integer=""> f){
        List result = new ArrayList();
        person.forEach(x -> result.add(f.apply(x)));
        return result;
    }
}
     |   |    |  
    | 类型 |  Person |  
  | 方法名 |  getAge |  
  | Lambda 方式 |  List allAges = ReferenceToInstanceMethodAOPT.listAllAges(persons, x -> x.getAge()); |  
  | Method Reference |  List allAges = ReferenceToInstanceMethodAOPT.listAllAges(persons, Person::getAge); |  
  
 4 . 特定对象的实例方法
 public class ReferenceToInstanceMethodOAPO {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        List names = new ArrayList();
            names.add("David");
            names.add("Richard");
            names.add("Samuel");
            names.add("Rose");
            names.add("John");
           ReferenceToInstanceMethodOAPO.printNames(names,System.out::println);
    }
    private static void printNames(List list, Consumer c ){
        list.forEach(x -> c.accept(x));
    }
}
     |   |    |  
    | 对象 |  System.out |  
  | 实例方法名 |  println |  
  | Lambda 方式 |  ReferenceToInstanceMethodOAPO.printNames(names, x -> System.out.println(x)); |  
  | Method Reference |  ReferenceToInstanceMethodOAPO.printNames(names,System.out::println); |