• java8


    http://blog.csdn.net/wwwsssaaaddd/article/details/37573517


    方法引用的概念

           某些lambda表达式里面仅仅是执行一个方法调用。在这种情况下,不用lambda表达式,直接通过方法名称引用方法的形式可读性更高一些,这种形式就是方法引用,方法引用是一种更简洁易懂的lambda 表达式。

    看下面这个Person类:

    public class Person {

           public enum Sex {

                  MALEFEMALE

           }

           String name;

           LocalDate birthday;

           Sex gender;

           String emailAddress;

           public int getAge() {

                  // ...

           }

           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()]);//可认为roster是你好友的名册

    class PersonAgeComparator implements Comparator<Person> {

    public int compare(Person a, Person b) {

            return a.getBirthday().compareTo(b.getBirthday());

        }

    }

    Arrays.sort(rosterAsArray, new PersonAgeComparator());

    sort方法定义如下:

    static <T> void sort(T[] a, Comparator<? super T> c)

           注意Comparator接口是一个函数接口。 因此,这里可以使用lambda表达式,省去了定义PersonAgeComparator 类和创建一个类实例,如下。

    Arrays.sort(rosterAsArray,

        (Person a, Person b) -> {

            return a.getBirthday().compareTo(b.getBirthday());

        }

    );

           然而, 比较两个Person对象的生日大小的方法Person.compareByAge,已经在Person类中定义了。 这样,在lambda表达式主体内直接调用Person.compareByAge就好了:

    Arrays.sort(rosterAsArray,

        (a, b) -> Person.compareByAge(a, b)

    );

           因为上面的lamdba表达式调用了一个现成的方法,所以可以用方法引用替代这个lamdba表达式:

    Arrays.sort(rosterAsArray,

       Person::compareByAge

    );

           方法引用Person::compareByAge跟lambda表达式(a, b) -> Person.compareByAge(a,b)在语义上是等价的。 两者有如下的特征 :

    ·   形参相同 ,都是(Person, Person)。

    ·   调用方法Person.compareByAge。

    方法引用的种类

    一共有四种类型的方法引用:

    类型

    示例

    类静态方法引用

    ContainingClass::staticMethodName

    某个对象的方法引用

    ContainingObject::instanceMethodName

    特定类的任意对象的方法引用

    ContainingType::methodName

    构造方法引用

    ClassName::new

    1)静态方法引用

    方法引用Person::compareByAge 就是对一个静态方法引用。

    2)某个对象的方法引用

    下面就是一个对特定对象的实例方法引用的例子:

    class ComparisonProvider {

        public int compareByName(Person a, Person b) {

            return a.getName().compareTo(b.getName());

        }

        public int compareByAge(Person a, Person b) {

            return a.getBirthday().compareTo(b.getBirthday());

        }

    }

    ComparisonProvider myComparisonProvider = new ComparisonProvider();

    Arrays.sort(rosterAsArray, myComparisonProvider::compareByName);

    这个方法引用 myComparisonProvider::compareByName 调用了myComparisonProvider对象的compareByName方法。JRE 会推断出方法的类型参数,比如在这个例子中是(Person, Person)。

    3)特定类的任意对象的方法引用

    String[]stringArray = { "Barbara""James""Mary""John",

        "Patricia""Robert""Michael""Linda" };

    Arrays.sort(stringArray, String::compareToIgnoreCase);

           与这个方法引用String::compareToIgnoreCase等价的lambda表达式要有形参列表(String a, String b),此处a和b是随意取的名字。这个方法引用将会触发a.compareToIgnoreCase(b) 方法执行。

    4)构造方法引用

           使用new关键词引用构造方法就像引用类静态方法一样。下面方法实现了从一个集合复制其元素到另一个集合中:

    public static <T, SOURCE extends Collection<T>, DEST extends Collection<T>>

        DEST transferElements(

            SOURCEsourceCollection,

            Supplier<DEST>collectionFactory) {

          DESTresult = collectionFactory.get();

            for (T t : sourceCollection) {

               result.add(t);

            }

            return result;

    }

           函数接口Supplier有一个方法get,get无输入参数,输出是一个对象。这样,你可以使用一个lambda 表达式调用transferElements方法,如下所示:

    Set<Person>rosterSetLambda =

        transferElements(roster, () -> { return new HashSet<>(); });

           进一步,你可以使用构造方法引用来替代lambda 表达式:

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

           Java编译器推断出你想创建一个HashSet集合,其中包含Person类型的元素。当然,你也可以像下面这样显式的指定集合元素的类型为Person

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

     

    http://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html

     


  • 相关阅读:
    IO多路复用 IO异步
    你没听说过的协程
    事件驱动和IO操作
    堡垒机前戏——paramiko
    听说过的多进程,多线程到底是什么鬼
    socket套接字
    看见就烦的异常
    struts2值栈内部数据结构详解
    hibernate一级缓存的源码初窥
    使用自定义标签模拟jstl的<c:for each>标签
  • 原文地址:https://www.cnblogs.com/leeeee/p/7276094.html
Copyright © 2020-2023  润新知