JAVA 8 '::' 关键字,带你深入了解它!

::关键字提供了四种语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,::关键字可以使语言更简洁,减少冗余代码。


























语法种类 示例
引用静态方法 ContainingClass::staticMethodName
引用特定对象的实例方法 containingObject::instanceMethodName
引用特定类型的任意对象的实例方法 ContainingType::methodName
引用构造函数 ClassName::new

文章目录

    • 引用静态方法
    • 引用特定对象的实例方法
    • 引用特定类型的任意对象的实例方法
    • 引用构造函数

引用静态方法

  1. public class Person {
  2. public enum Sex {
  3. MALE, FEMALE
  4. }
  5. String name;
  6. LocalDate birthday;
  7. Sex gender;
  8. String emailAddress;
  9. public int getAge() {
  10. // ...
  11. }
  12. public Calendar getBirthday() {
  13. return birthday;
  14. }
  15. public static int compareByAge(Person a, Person b) {
  16. return a.birthday.compareTo(b.birthday);
  17. }}

假设您的社交网络应用程序的成员包含在一个数组中,并且您想按年龄对数组进行排序。您可以使用以下代码(在示例中找到本节中描述的代码摘录 MethodReferencesTest):

  1. Person[] rosterAsArray = roster.toArray(new Person[roster.size()]);
  2. class PersonAgeComparator implements Comparator<Person> {
  3. public int compare(Person a, Person b) {
  4. return a.getBirthday().compareTo(b.getBirthday());
  5. }
  6. }
  7. Arrays.sort(rosterAsArray, new PersonAgeComparator());

调用的方法签名如下:

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

请注意,该接口Comparator是功能接口。因此,您可以使用lambda表达式,而不是定义并创建一个新类的实例,该实例实现Comparator

  1. Arrays.sort(rosterAsArray,
  2. (Person a, Person b) -> {
  3. return a.getBirthday().compareTo(b.getBirthday());
  4. }
  5. );

但是,这种用于比较两个Person实例的出生日期的方法已经存在Person.compareByAge。您可以改为在lambda表达式的主体中调用此方法:

  1. Arrays.sort(rosterAsArray,
  2. (a, b) -> Person.compareByAge(a, b)
  3. );

由于此lambda表达式会调用现有方法,因此您可以使用方法引用代替lambda表达式:

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

方法引用Person::compareByAge在语义上与lambda表达式相同(a, b) -> Person.compareByAge(a, b)。每个都有以下特征:

  • 它的形参列表是从复制Comparator<Person>.compare,这是(Person, Person)
  • 它的主体调用该方法Person.compareByAge

引用特定对象的实例方法

以下是对特定对象的实例方法的引用示例:

  1. class ComparisonProvider {
  2. public int compareByName(Person a, Person b) {
  3. return a.getName().compareTo(b.getName());
  4. }
  5. public int compareByAge(Person a, Person b) {
  6. return a.getBirthday().compareTo(b.getBirthday());
  7. }
  8. }
  9. ComparisonProvider myComparisonProvider = new ComparisonProvider();
  10. Arrays.sort(rosterAsArray, myComparisonProvider::compareByName);

方法引用myComparisonProvider::compareByName调用compareByName作为对象一部分的方法myComparisonProviderJRE推断方法类型参数,在这种情况下为(Person, Person)

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

以下是对特定类型的任意对象的实例方法的引用示例:

  1. String[] stringArray = { "Barbara", "James", "Mary", "John",
  2. "Patricia", "Robert", "Michael", "Linda" };
  3. Arrays.sort(stringArray, String::compareToIgnoreCase);

方法参考的等效lambda表达式String::compareToIgnoreCase将具有形式参数列表(String a, String b),其中ab是用于更好地描述此示例的任意名称。方法引用将调用该方法a.compareToIgnoreCase(b)

引用构造函数

您可以使用name以与静态方法相同的方式引用构造函数new。以下方法将元素从一个集合复制到另一个:

  1. public static <T, SOURCE extends Collection<T>, DEST extends Collection<T>>
  2. DEST transferElements(
  3. SOURCE sourceCollection,
  4. Supplier<DEST> collectionFactory) {
  5. DEST result = collectionFactory.get();
  6. for (T t : sourceCollection) {
  7. result.add(t);
  8. }
  9. return result;
  10. }

功能接口Supplier包含一个get不带任何参数并返回一个对象的方法。因此,您可以transferElements使用lambda表达式调用该方法,如下所示:

  1. Set<Person> rosterSetLambda =
  2. transferElements(roster, () -> { return new HashSet<>(); });

您可以使用构造函数引用代替lambda表达式,如下所示:

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

Java编译器推断您要创建一个HashSet包含type元素的集合Person。或者,您可以指定以下内容:

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

开心一刻

局长与科长共乘电梯,局长放一屁后对科长说:你放屁了!科长说:不是我放的…不久科长被免职,局长在会上说:屁大的事你都担待不起,要你何用?
在这里插入图片描述

翻译不易,如果觉得不错的,请帮忙点个赞!!!

发表评论

表情:
评论列表 (有 0 条评论,15人围观)

还没有评论,来说两句吧...

相关阅读

    相关 8张图深入理解Java

    有时候一张图往往胜过千言万语。下列的图是来自于Program Creek的Java教程,这是至今为止最受欢迎的文章。希望这些图能够帮助你复习已经学习到的知识。如果你通过这些图还