fundamentals\java\java8新特性-MethodReferences(译自oracle官网)

Method References

目录

Method References

方法引用种类:Kinds of Method References

引用类的静态方法:Reference to a Static Method

引用对象的成员方法:Reference to an Instance Method of a Particular Object

引用对象的特定类型成员方法:Reference to an Instance Method of an Arbitrary Object of a Particular Type

引用构造函数:Reference to a Constructor


You use lambda expressions to create anonymous methods. Sometimes, however, a lambda expression does nothing but call an existing method. In those cases, it's often clearer to refer to the existing method by name. Method references enable you to do this; they are compact, easy-to-read lambda expressions for methods that already have a name.

您可以使用lambda表达式来创建匿名方法。然而,有时候,lambda表达式除了调用现有的方法之外什么也不做。

在这些情况下,使用名称引用现有的方法通常更清楚。

方法引用使您能够做到这一点;它们是紧凑的、易于阅读的lambda表达式,用于引用有名称的方法。

Consider again the Person class discussed in the section Lambda Expressions:

再考虑一下在Lambda表达式中讨论的Person类:

public class Person {

    public enum Sex {

        MALE, FEMALE

    }

    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);

    }

}

假设用数组来保存会员,您希望按年龄对数组进行排序。您可以使用下面的代码:Suppose that the members of your social networking application are contained in an array, and you want to sort the array by age. You could use the following code (find the code excerpts described in this section in the example MethodReferencesTest):

// you want to sort the array by age.

// 你想按年龄对数组进行排序

Person[] rosterAsArray = roster.toArray(new Person[roster.size()]);

 

class PersonAgeComparator implements Comparator<Person> {

    public int compare(Person a, Person b) {

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

    }

}

       

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

 

// The method signature of this invocation of sort is the following:

// 调用的排序 sort 接口如下:

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

 

// Notice that the interface Comparator is a functional interface.

// Therefore, you could use a lambda expression instead of defining

// and then creating a new instance of a class that implements Comparator:

// 注意,上栗中 sort接口是一个功能接口。因此,您可以使用lambda表达式,简化代码

Arrays.sort(rosterAsArray,

    (Person a, Person b) -> {

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

    }

);

 

// However, this method to compare the birth dates of two Person instances already exists as Person.

// compareByAge. You can invoke this method instead in the body of the lambda expression:

// 然而,这种比较两个Person实例的出生日期的方法已经存在compareByAge()。你可以在lambda表达式的主体中调用这个方法

Arrays.sort(rosterAsArray,

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

);

 

// Because this lambda expression invokes an existing method, you can use a method reference instead of a lambda expression:

// 因为这个lambda表达式调用了一个现有的方法,所以您可以使用一个方法引用而不是lambda表达式:

Arrays.sort(rosterAsArray, Person::compareByAge);

The method reference Person::compareByAge is semantically the same as the lambda expression (a, b) -> Person.compareByAge(a, b). Each has the following characteristics:

  • Its formal parameter list is copied from Comparator<Person>.compare, which is (Person, Person).
  • Its body calls the method Person.compareByAge.

方法引用Person::compareByAge lambda表达式(a, b) -> Person.compareByAge(a, b).代表了相同的语义。他们有如下特征:

  1. 它的参数列表都是(Person, Person)Comparator的参数列表;
  2. 在方法体中调用Person.compareByAge()方法;

Kinds of Method References

There are four kinds of method references:

Kind

Example

Reference to a static method

ContainingClass::staticMethodName

Reference to an instance method of a particular object

containingObject::instanceMethodName

Reference to an instance method of an arbitrary object of a particular type

ContainingType::methodName

Reference to a constructor

ClassName::new

 

有四种方法引用:

Kind

Example

引用类的静态方法

ContainingClass::staticMethodName

引用对象的成员方法

containingObject::instanceMethodName

引用类的任意对象成员方法

ContainingType::methodName

引用构造方法

ClassName::new

Reference to a Static Method

The method reference Person::compareByAge is a reference to a static method.

Person::compareByAge就是一个引用类的静态方法的栗子。

Reference to an Instance Method of a Particular Object

The following is an example of a reference to an instance method of a particular object:

下面是栗子:

// 比较 供应器封装了Person类所有属性的比较方法,

// 本例中使用比较供应器ComparisonProvider的成员方法compareByName实现比较

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);

 

The method reference myComparisonProvider::compareByName invokes the method compareByName that is part of the object myComparisonProvider. The JRE infers the method type arguments, which in this case are (Person, Person).

JRE会推断出方法类型参数,在本例中是(PersonPerson

Reference to an Instance Method of an Arbitrary Object of a Particular Type

The following is an example of a reference to an instance method of an arbitrary object of a particular type:

下面是任意对象的方法引用的栗子:

// The equivalent lambda expression for the method reference String::compareToIgnoreCase would have the formal parameter list (String a, String b),

// where a and b are arbitrary names used to better describe this example. The method reference would invoke the method a.compareToIgnoreCase(b).

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

    "Patricia", "Robert", "Michael", "Linda" }; // 一数组的任意对象

Arrays.sort(stringArray, String::compareToIgnoreCase); // 等价于:a.compareToIgnoreCaseb

 

Reference to a Constructor

// You can reference a constructor in the same way as a static method by using the name new. The following method copies elements from one collection to another:

// 您可以通过使用new来引用构造函数,和引用静态方法一样。下面的方法将元素从一个集合复制到另一个集合:

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

    DEST transferElements(

        SOURCE sourceCollection,

        Supplier<DEST> collectionFactory) {

       

        DEST result = collectionFactory.get();

        for (T t : sourceCollection) {

            result.add(t);

        }

        return result;

}

 

// The functional interface Supplier contains one method get that takes no arguments and returns an object.

// Consequently, you can invoke the method transferElements with a lambda expression as follows:

// 功能接口Supplier包含一个方法,它不接受任何参数,并返回一个对象。

// 因此,您可以用lambda表达式调用transferelement方法:

Set<Person> rosterSetLambda =

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

   

// You can use a constructor reference in place of the lambda expression as follows:

// 您可以也使用引用构造方法来代替lambda表达式,如下所示

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

 

// The Java compiler infers that you want to create a HashSet collection that contains elements of type Person.

// Alternatively, you can specify this as follows:

// java编译器推断你想要创建一个HashSet集合,用来存储Person对象。等同于如下表达式:

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

 

猜你喜欢

转载自blog.csdn.net/u012296499/article/details/81706097
今日推荐