JDK8 新特性-方法引用

什么是方法引用

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

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

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

方法引用的三种语法格式

1.对象::实例方法名

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

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

        //方法引用
        Consumer 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 {
    void accept(T t);
}
image.png

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

2.类::静态方法名.

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

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

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

        //静态方法引用
        Consumer 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 consumer = new Consumer() {
            @Override
            public void accept(String s) {
                System.out.println("匿名内部类测试:" + s);
            }
        };

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

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

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

        //类::实例方法名 引用
        BiPredicate predicate = new BiPredicate() {
            @Override
            public boolean test(String s1, String s2) {
                return s1.equals(s2);
            }
        };
        BiPredicate predicate1 = (x,y) -> x.equal(y);
        BiPredicate 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 {
    boolean test(T t, U u);
}

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

二、构造器引用

类::new

匿名内部类及lambda写法:

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

构造器引用写法:

   Supplier supplier2 = testConsumer::new;

Supplier接口:

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

三、数组引用

Type::new

匿名内部类及lambda语法

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

数组引用写法:

 Function fun = String[]::new;

总结

  • 方法应用及构造器引用其实可以理解为lamdba的另一种表现形式
  • 方法引用被调用的方法的参数列表和返回值类型需要与函数式接口中抽象方法的参数列表和返回值类型要一致
  • 方法引用中使用类::实例方法的条件是第一个参数是这个实例方法的调用者,第二个参数是这个实例方法的参数
  • 构造器引用需要调用的构造器的参数列表要与函数式接口中抽象方法的参数列表一致

你可能感兴趣的:(JDK8 新特性-方法引用)