您的位置 首页 java

java 8新特性 方法引用

Lambda的冗余场景

使用 Lambda表达式 求一个数组的和

 public class Demo11MethodRefIntro {
public  static  void getMax(int[] arr) {
    int sum = 0;
    for (int n : arr) {
         sum += n;
   }
    System.out.println(sum);
}
public static void main(String[] args) {
    printMax((int[] arr) -> {
        int sum = 0;
        for (int n : arr) {
             sum += n;
        }
         System.out.println(sum);
     });
}
 private  static void printMax(Consumer<int[]> consumer) {
    int[] arr = {10, 20, 30, 40, 50};
    consumer.accept(arr);
    }
}
  

体验方法引用简化Lambda

如果我们在Lambda中所指定的功能,已经有其他方法存在相同方案,那是否还有必要再写重复逻辑?

可以直接“引 用”过去就好了:

 public class DemoPrintRef {
    public static void getMax(int[] arr) {
        int sum = 0;
        for (int n : arr) {
            sum += n;
}
    System.out.println(sum);
}
public static void main(String[] args) {
    printMax(Demo11MethodRefIntro::getMax);
}
private static void printMax(Consumer<int[]> consumer) {
        int[] arr = {10, 20, 30, 40, 50};
        consumer.accept(arr);
    }
}  

请注意其中的双冒号 :: 写法,这被称为“ 方法引用 ”,是一种新的语法。

方法引用的格式

符号表示 : ::

符号说明 : 双冒号为方法引用运算符,而它所在的表达式被称为 方法引用

应用场景 : 如果Lambda所要实现的方案 , 已经有其他方法存在相同方案,那么则可以使用方法引用。

常见引用方式

方法引用在JDK 8中使用方式相当灵活,有以下几种形式:

  1. instanceName::methodName 对象::方法名
  2. ClassName::staticMethodName 类名:: 静态方法
  3. ClassName::methodName 类名::普通方法
  4. ClassName::new 类名::new 调用的构造器
  5. TypeName[]::new String[]::new 调用数组的构造器

对象名::引用成员方法

这是最常见的一种用法,与上例相同。如果一个类中已经存在了一个成员方法,则可以通过对象名引用成员方法,

代码为:

 // 对象::实例方法
@Test
public void test01() {
    Date now = new Date();
    
    Supplier<Long> supp = () -> {
        return now.getTime();
    };
    System.out.println(supp.get());
    
    Supplier<Long> supp2 = now::getTime;
    System.out.println(supp2.get());
}
  

方法引用的注意事项

  1. 被引用的方法,参数要和接口中抽象方法的参数一样
  2. 当接口抽象方法有返回值时,被引用的方法也必须有返回值

类名::引用静态方法

由于在 java.lang.System 类中已经存在了静态方法 currentTimeMillis ,所以当我们需要通过Lambda来调用该 方法时,可以使用方法引用 , 写法是:

 // 类名::静态方法
@Test
public void test02() {
    Supplier<Long> supp = () -> {
        return System.currentTimeMillis();
    };
    System.out.println(supp.get());

    Supplier<Long> supp2 = System::currentTimeMillis;
    System.out.println(supp2.get());
}  

类名::引用实例方法

Java面向对象中,类名只能调用静态方法,类名引用实例方法是有前提的,实际上是拿第一个参数作为方法的调用者。

 // 类名::实例方法
@Test
public void test03() {
    Function<String,  Integer > f1 = (s) -> {
        return s.length();
};
    System.out.println(f1.apply("abc"));

    Function<String, Integer> f2 = String::length;
    System.out.println(f2.apply("abc"));
    
    Bi Function <String, Integer, String> bif = String::substring;
    String hello = bif.apply("hello", 2);
    System.out.println("hello = " + hello);
}
  

类名::new引用构造器

由于构造器的名称与类名完全一样。所以构造器引用使用 类名称::new 的格式表示。首先是一个简单的 Person 类:

 public class Person {
    private String name;
    public Person(String name) {
        this.name = name;
}

    public String getName() {
        return name;
    }
}
  

要使用这个函数式接口,可以通过方法引用传递:

 // 类名::new
@Test
public void test04() {
    Supplier<Person> sup = () -> {
    return new Person();
};
System.out.println(sup.get());

    Supplier<Person> sup2 = Person::new;
    System.out.println(sup2.get());
    
    BiFunction<String, Integer, Person> fun2 = Person::new;
    System.out.println(fun2.apply("张三", 18));
}
  

数组::new 引用数组构造器

数组也是 Object 的子类对象,所以同样具有构造器,只是语法稍有不同。

 // 类型[]::new
@Test
public void test05() {
    Function<Integer, String[]> fun = (len) -> {
    return new String[len];
 };
    String[] arr1 = fun.apply(10);
    System.out.println(arr1 + ", " + arr1.length);

    Function<Integer, String[]> fun2 = String[]::new;
    String[] arr2 = fun.apply(5);
    System.out.println(arr2 + ", " + arr2.length);
}
  

小结

方法引用是对Lambda表达式符合特定情况下的一种缩写,它使得我们的Lambda表达式更加的精简,也可以理解为 Lambda表达式的缩写形式 , 不过要注意的是方法引用只能”引用”已经存在的方法!

文章来源:智云一二三科技

文章标题:java 8新特性 方法引用

文章地址:https://www.zhihuclub.com/198394.shtml

关于作者: 智云科技

热门文章

网站地图