双冒号::在JDK8的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);
}}
假设某个社交网络APP包含成员的个人信息,你想根据年龄age来排序:
Person[] rosterAsArray = roster.toArray(new Person[roster.size()]);
class PersonAgeComparator implements Comparator {
public int compare(Person a, Person b) {
return a.getBirthday().compareTo(b.getBirthday());
}
}
Arrays.sort(rosterAsArray, new PersonAgeComparator());
我们有一个方法引用,如:
static void sort(T[] a, Comparator super T> c)
请注意,此时的接口Comparator是一个用 @Functional 来注解的,所以你可以用一个Lambda表达式来写方法定义,来创建Comparator的实例:
Arrays.sort(rosterAsArray,
(Person a, Person b) -> {
return a.getBirthday().compareTo(b.getBirthday());
}
);
在Person.compareByAge函数中,其instance已存在,所以我们要比较两个Person实例的年龄大小,用Lambda expression可以这样写:
Arrays.sort(rosterAsArray,
(a, b) -> Person.compareByAge(a, b)
);
由于咱们的Lambda表达式调用的是一个已经存在的方法,即,我们做的就是方法引用,所以你就可以用双冒号::来改造一下:
Arrays.sort(rosterAsArray, Person::compareByAge);
以下是Oracle官网对Lambda表达式的一段说明:
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.
一共有4种这样的类型引用:KindExample
对静态方法的引用ContainingClass::staticMethodName
对一个特定对象的实例方法的引用containingObject::instanceMethodName
对一个任意对象特定类型的实例方法的引用ContainingType::methodName
对构造函数的引用ClassName::new
官网例子参考: