JDK8 新特性-方法引用

什么是方法引用

方法引用就是通过类名或方法名引用已经存在的方法来简化lambda表达式。

什么时候可以使用方法引用

如果lamdba体中的内容已经有方法实现了,我们就可以使用方法引用。

方法引用的三种语法格式

1.对象::实例方法名

public class testConsumer {
    public static void main(String[] args) {
        //匿名内部类
        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println("匿名内部类测试:" + s);
            }
        };

        //lambda表达式
        Consumer consumer1 = x -> System.out.println("lambda表达式测试:" + x);

        //方法引用
        Consumer<String> consumer2 = new testConsumer()::reference1;

        consumer.accept("匿名内部类");
        consumer1.accept("lambda表达式");
        consumer2.accept("方法引用");
    }

    public void reference1(String name) {
        System.out.println("方法引用测试:" + name);
    }
}

consumer接口:

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}
image.png

注意:被调用的方法的参数列表和返回值类型需要与函数式接口中抽象方法的参数列表和返回值类型要一致。

2.类::静态方法名.

public class testConsumer {
    public static void main(String[] args) {
        //匿名内部类
        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println("匿名内部类测试:" + s);
            }
        };

        //lambda表达式
        Consumer consumer1 = x -> System.out.println("lambda表达式测试:" + x);

        //方法引用
        Consumer<String> consumer2 = new testConsumer()::reference1;

        //静态方法引用
        Consumer<String> consumer3 = testConsumer::reference2;

        consumer.accept("匿名内部类");
        consumer1.accept("lambda表达式");
        consumer2.accept("方法引用");
        consumer3.accept("静态方法引用");

    }

    public void reference1(String name) {
        System.out.println("方法引用测试:" + name);
    }
    public static void reference2(String name){
        System.out.println("方法引用测试:"+name);
    }
}

*注意:被调用的方法的参数列表和返回值类型需要与函数式接口中抽象方法的参数列表和返回值类型要一致。

image.png

3. 类::实例方法名

public class testConsumer {
    private static final String aa =  "aa";
    private static final String bb =  "bb";

    public static void main(String[] args) {

        //匿名内部类
        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println("匿名内部类测试:" + s);
            }
        };

        //lambda表达式
        Consumer consumer1 = x -> System.out.println("lambda表达式测试:" + x);

        //对象::实例方法名 引用
        Consumer<String> consumer2 = new testConsumer()::reference1;

        //类::静态方法名 引用
        Consumer<String> consumer3 = testConsumer::reference2;

        //类::实例方法名 引用
        BiPredicate<String,String> predicate = new BiPredicate<String, String>() {
            @Override
            public boolean test(String s1, String s2) {
                return s1.equals(s2);
            }
        };
        BiPredicate<testConsumer,String> predicate1 = (x,y) -> x.equal(y);
        BiPredicate<testConsumer,String> predicate2 = testConsumer::equal;

        consumer.accept("匿名内部类");
        consumer1.accept("lambda表达式");
        consumer2.accept("对象::方法名引用");
        consumer3.accept("类::静态方法名引用");
        System.out.println(predicate2.test(new testConsumer(),"bb"));
    }

    public void reference1(String name) {
        System.out.println("方法引用测试:" + name);
    }
    public static void reference2(String name){
        System.out.println("方法引用测试:"+name);
    }

    public boolean equal(String a){
        System.out.println("类::实例方法名引用");
        return a.equals(bb);
    }
}

BiPredicate接口:

@FunctionalInterface
public interface BiPredicate<T, U> {
    boolean test(T t, U u);
}

注意:第一个参数是这个实例方法的调用者,第二个参数是这个实例方法的参数时,就可以使用这种语法。

二、构造器引用

类::new

匿名内部类及lambda写法:

  //构造器引用
        Supplier<testConsumer> supplier = new Supplier<testConsumer>() {
            @Override
            public testConsumer get() {
                return new testConsumer();
            }
        };
        Supplier<testConsumer> supplier1 = () -> new testConsumer();

构造器引用写法:

   Supplier<testConsumer> supplier2 = testConsumer::new;

Supplier接口:

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

三、数组引用

Type::new

匿名内部类及lambda语法

 //数组引用
        Function<Integer,String[]>  function = new Function<Integer, String[]>() {
            @Override
            public String[] apply(Integer s) {
                return new String[s];
            }
        };
Function<Integer,String[]> fun = x -> new String[x];

数组引用写法:

 Function<Integer, String[]> fun = String[]::new;

总结

  • 方法应用及构造器引用其实可以理解为lamdba的另一种表现形式
  • 方法引用被调用的方法的参数列表和返回值类型需要与函数式接口中抽象方法的参数列表和返回值类型要一致
  • 方法引用中使用类::实例方法的条件是第一个参数是这个实例方法的调用者,第二个参数是这个实例方法的参数
  • 构造器引用需要调用的构造器的参数列表要与函数式接口中抽象方法的参数列表一致
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容