Lambda表达式系列历史文章

玩转Java8 lambda表达式及自定义函数式接口入门
玩转java8 Lambda表达式一
玩转java8 Lambda表达式之静态方法引用


什么是方法引用?

Lambda还有一个非常重要的功能,就是方法引用。方法引用可以理解为lambda表达式的简便写法。方法引用是用来直接访问类或者实例的已经存在的方法或构造方法(函数),它比lambda表达式更加的简洁,更高的可读性,更好的复用性。

方法引用的语法

类名(或实例)::方法名

方法引用的分类

image


实例方法引用的定义

如果函数式接口的实现恰好可以通过一个实例的实例方法来实现,那么就可以使用实例方法引用。

实例方法引用的示例

废话少说,直接上干货,代码示例中都有重要注释

this关键字方法引用

class Father5 {
    public void f1() {
        System.out.println("f1 method...");
    }
    public String f2() {
        /**
         * f2方法调用f1方法,就可以使用this 对象调用
         */
        Runnable r1 = this::f1;
        System.out.println("f2 method...");
        return "f2";
    }
}

super关键字方法引用

class Father5 {
    public void f1() {
        System.out.println("f1 method...");
    }
    public String f2() {
        /**
         * f2方法调用f1方法,就可以使用this 对象调用
         */
        Runnable r1 = this::f1;
        System.out.println("f2 method...");
        return "f2";
    }
}

class Son extends Father5{
    @Override
    public void f1() {
        /**
         *super关键字使用方法引用,调用父类f1方法
         */
        Runnable r1 = super::f1;
        System.out.println();
    }

    @Override
    public String f2() {
        return super.f2();
    }
}

无参数,无返回值

public class LambdaInstanceMethodTest {

    /**
     * 测试无参,无返回值
     */
    @Test
    public void test() {
        /**
         * 可以在body体直接new Father实例调用,如r1
         * 也可以先创建实例对象father,再进行调用,如r2
         */
        Runnable r1 = () -> new Father().f1();
        Father father = new Father();
        Runnable r2 = () -> father.f1();

        /**
         * 将r2改写为实例方法调用
         */
        Runnable r3 = father::f1;

        r1.run();
        r2.run();
        r3.run();

        /**
         * 也可以引用有返回值的方法,只要方法没有参数即可,如f2方法
         */
        Runnable r4 = father::f2;
        r4.run();
    }


}

class Father {
    public void f1() {
        System.out.println("f1 method...");
    }
    public String f2() {
        System.out.println("f2 method...");
        return "f2";
    }
}

无参数,有返回值

public class LambdaInstanceMethodTest2 {

    /**
     * 测试无参,有返回值
     */
    @Test
    public void test() {
        /**
         * java.util.function.Supplier java8自带的函数式接口
         *
         * 可以在body体直接new Father2实例调用,如s1
         * 也可以先创建实例对象father2,再进行调用,如s2
         */
        Supplier<String> s1 = () -> new Father2().f2();
        Father2 father2 = new Father2();
        Supplier<String> s2 = () -> father2.f2();

        /**
         * 将s2改写为实例方法调用
         */
        Supplier<String> s3 = father2::f2;

        s1.get();
        s2.get();
        s3.get();
    }


}

class Father2 {

    public String f2() {
        System.out.println("f2 method...");
        return "f2";
    }
}

有参数,无返回值

public class LambdaInstanceMethodTest3 {

    /**
     * 测试有参,无返回值
     */
    @Test
    public void test() {
        /**
         * java.util.function.Consumer java8自带的函数式接口
         *
         * 可以在body体直接new Father3实例调用,如c1\c2
         * 也可以先创建实例对象father3,再进行调用,如c3\c4
         */
        Consumer<String> c1 = str-> new Father3().f1(str);
        Consumer<String> c2 = str-> new Father3().f3(str);
        Father3 father3 = new Father3();
        Consumer<String> c3 = str-> father3.f1(str);
        Consumer<String> c4 = str-> father3.f3(str);

        /**
         * 将c3/c4改写为实例方法调用
         */
        Consumer<String> c5 = father3::f1;
        Consumer<String> c6 = father3::f3;

        c1.accept("lambda 1");
        c2.accept("lambda 2");
        c3.accept("lambda 3");
        c4.accept("lambda 4");
        c5.accept("lambda 5");
        c6.accept("lambda 6");

    }


}

class Father3 {
    public void f1(String s) {
        System.out.println("f1 method...");
    }

    public String f3(String s) {
        System.out.println("f3 method..."+s);
        return "f3";
    }
}

有参数,有返回值

public class LambdaInstanceMethodTest4 {

    /**
     * 测试有参数,有返回值
     */
    @Test
    public void test() {
        /**
         * java.util.function.Function\java.util.function.BiFunction java8自带的函数式接口
         *
         * 可以在body体直接new Father4实例调用,如f1\f2
         * 也可以先创建实例对象father4,再进行调用,如f3\f4
         */
        Function<String, Integer> f1 = str -> new Father4().f3(str);
        BiFunction<String,String, Integer> f2 = (s1,s2) -> new Father4().f4(s1,s2);
        Father4 father4 = new Father4();
        Function<String, Integer> f3 = str -> father4.f3(str);
        BiFunction<String,String, Integer> f4 = (s1,s2) -> father4.f4(s1,s2);

        /**
         * 将f3/f4改写为实例方法调用
         */
        Function<String, Integer> f5 = father4::f3;
        BiFunction<String,String, Integer> f6 = father4::f4;

        System.out.println(f1.apply("lambda 1"));
        System.out.println(f2.apply("java","lambda 1"));
        System.out.println(f3.apply("lambda 2"));
        System.out.println(f4.apply("java", "lambda 2"));
        System.out.println(f5.apply("lambda 3"));
        System.out.println(f6.apply("java", "lambda 3"));

    }


}

class Father4 {
    public Integer f3(String s) {
        System.out.println("f3 method..." + s);
        return s.length();
    }

    public Integer f4(String s1, String s2) {
        System.out.println("f4 method...");
        return s1.length() + s2.length();
    }
}

本文分享了Lambda表达式的实例方法引用。如有不妥之处,欢迎拍砖。
下一章将分享Lambda表达式的对象方法引用,请大家继续关注。
image

孤天一鹤
2 声望0 粉丝