美文网首页
Java Lambda表达式之方法引用

Java Lambda表达式之方法引用

作者: 小生yy | 来源:发表于2019-11-14 15:01 被阅读0次

话接上篇,在上篇《Java Lambda表达式简介及入门》中我们介绍了lambda表达式的一些基本用法,在基本用法里面有时候抽象方法的实现是直接调用另外的一个方法来实现的,比如下面的例子,对于这种情况,我么有可能使用方法的引用来简化代码。

Consumer<String> co = s -> System.out.println(s);
Function<String, Integer> f = s -> s.length();

但是转换为方法的引用,将是本章的主要内容。
代码下载

什么是方法的引用

方法引用是用来直接访问类或者实例的已经存在的方法或者构造方法,方法引用提供了一种引用而不执行方法的方式,如果抽象方法的实现恰好可以使用调用另外一个方法来实现,就有可能可以使用方法引用

方法引用的分类

方法引用分类.png

根据上表可知方法引用有四类,接下来会介绍一种类型的用法。

静态方法的引用

静态方法引用的含义

如果函数式接口的实现恰好可以通过调用一个静态方法来实现,那么就可以使用静态方法引用
语法: 类名::staticMethod

静态方法引用示例

直接先上代码:

public class lambda02 {

    public static String put() {
        return "hello";
    }

    public static void fun(Integer a) {
        System.out.println(a);
    }

    public static Integer len(String str) {
        return str.length();
    }

    public static void main(String[] args) {
        //无参有返回值
        Supplier<String> s1 = () -> "hello";
        Supplier<String> s2 = () -> lambda02.put();
        Supplier<String> s3 = lambda02::put;
        System.out.println(s3.get());

        //有参无返回值
        Consumer<Integer> c1 = a -> System.out.println(a);
        Consumer<Integer> c2 = a -> lambda02.fun(a);
        Consumer<Integer> c3 = lambda02::fun;
        c3.accept(999);

        //有参有返回值
        Function<String, Integer> f1 = s -> s.length();
        Function<String, Integer> f2 = s -> lambda02.len(s);
        Function<String, Integer> f3 = lambda02::len;
        System.out.println(f3.apply("hello"));
    }
}

执行结果:


静态方法引用结果.png

Supplier<T>是无参有返回值的函数式接口,
17行抽象方法的实现中我们简单的返回一个“hello”字符串
18行有一个静态函数put正好可以满足我们的需求,直接调用该方法
19行,根据静态方法引用的含义,将其改为静态方法引用的写法,类名::staticMethod,即lambda02::put。
Consumer<T>和Function<T, R>的示例类似。

实例方法引用

实例方法引用的含义

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

实例方法引用示例

直接先上代码:

public class lambda03 {
    public String put() {
        return "hello";
    }

    public void fun(Integer a) {
        System.out.println(a);
    }

    public Integer len(String str) {
        return str.length();
    }

    public void callthis() {
        System.out.println("call this");
        Function<String, Integer> f4 = this::len;
        System.out.println(f4.apply("callthis"));
    }

    public static void main(String[] args) {
        Supplier<String> s1 = () -> "hello";
        Supplier<String> s2 = () -> new lambda03().put();
        Supplier<String> s3 = new lambda03()::put;
        System.out.println(s3.get());

        Consumer<Integer> c1 = a -> System.out.println(a);
        Consumer<Integer> c2 = a -> new lambda03().fun(a);
        Consumer<Integer> c3 = new lambda03()::fun;
        c3.accept(999);

        lambda03 exam = new lambda03();
        Function<String, Integer> f1 = s -> s.length();
        Function<String, Integer> f2 = s -> exam.len(s);
        Function<String, Integer> f3 = exam::len;
        System.out.println(f3.apply("hello"));
        exam.callthis();

    }
}

执行结果:


实例方法引用结果.png

实例方法引用和静态方法引用类似
21行抽象方法的实现中我们简单的返回一个“hello”字符串
22行有一个实例方法put正好可以满足我们的需求,可以调用实例对象的该方法
19行,根据实例方法引用的含义,将其改为实例方法引用的写法,inst::instMethod,即new lambda03()::put。
Consumer<T>和Function<T, R>的示例类似。
因为是实例对象,所以在实例方法中我们可以使用this和super,14~18行演示了this的用法。

对象方法引用

对象方法引用的含义

抽象方法的第一个参数类型刚好是实例方法的类型,抽象方法剩余的参数恰好可以当做实例方法的参数。如果函数式接口的实现能由上面说的实例方法调用来实现的话,那么就可以使用对象方法引用
语法: 类名::instMethod

对象方法引用示例

直接先上代码:

public class lambda04 {

    public static void main(String[] args) {
        Consumer<Foo> c1 = (Foo foo) -> new Foo().foo();
        Consumer<Foo> c2 = Foo::foo;
        c1.accept(new Foo());
        c2.accept(new Foo());

        BiConsumer<Foo, String> c3 = (foo, str) -> new Foo().foo2(str);
        BiConsumer<Foo, String> c4 = Foo::foo2;
        c3.accept(new Foo(), "hello");
        c4.accept(new Foo(), "hello");

        BiFunction<Foo, String, Integer> c5 = (foo, str) -> new Foo().foo3(str);
        BiFunction<Foo, String, Integer> c6 = Foo::foo3;
        System.out.println(c5.apply(new Foo(), "LAMBDA"));
        System.out.println(c6.apply(new Foo(), "LAMBDA"));
    }
}

class Foo {

    public void foo() {
        System.out.println("invoke");
    }

    public void foo2(String str) {
        System.out.println("invoke:" + str);
    }

    public Integer foo3(String str) {
        return str.length();
    }
}

执行结果:


对象方法引用结果.png

对象方法引用相比前面两种方法引用复杂一些。根据其含义“抽象方法的第一个参数类型刚好是实例方法的类型,抽象方法剩余的参数恰好可以当做实例方法的参数”,第一个参数的类型需要是实例方法的类型,除了限定了第一个参数的类型,同时意味着抽象方法如果没有参数,是没有办法写成对象方法引用,所以Runnable,Supplier<T>这些是不能写成对象方法引用的。
4行 (Foo foo) -> new Foo().foo(),第一个参数foo的类型是Foo,实例方法foo()也是属于Foo类的,所以参数类型符合,除去第一个参数foo,就没有其他参数,实例方法foo也正好也没有参数,符合抽象方法剩余的参数恰好可以当做实例方法的参数。
5行 根据语法规则,改为对象方法的引用,即Foo::foo
9行 (foo, str) -> new Foo().foo2(str),第一个参数foo的类型是Foo,实例方法foo2()也是属于Foo类的,所以参数类型符合,除去第一个参数foo,还有一个String类型的参数,实例方法foo2正好也是需要一个String类型的入参,符合抽象方法剩余的参数恰好可以当做实例方法的参数。
10行 根据语法规则,改为对象方法的引用,即Foo::foo2
14行 BiFunction<T, U, R>的前两个泛型是参数类型,第三个是返回值类型。(foo, str) -> new Foo().foo3(str),第一个参数foo的类型是Foo,实例方法foo3()也是属于Foo类的,所以参数类型符合,除去第一个参数foo,还有一个String类型的参数,实例方法foo3正好也是需要一个String类型的入参,符合抽象方法剩余的参数恰好可以当做实例方法的参数。同时foo3的返回值类型也符合。
15行 根据语法规则,改为对象方法的引用,即Foo::foo3

构造方法引用

构造方法引用的含义

如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用
类名::new

构造方法引用示例

直接先上代码:

public class lambda05 {
    public static void main(String[] args) {
        //无参数有返回值
        Supplier<Person> s1 = () -> new Person();
        Supplier<Person> s2 = Person::new;
        s1.get();
        s2.get();

        Supplier<Thread> S3 = Thread::new;
        Supplier<List> s4 = ArrayList::new;
        Supplier<Map> s5 = HashMap::new;

        //有参数无返回值
        Consumer<Integer> c1 = age -> new Person(age);
        Consumer<Integer> c2 = Person::new;
        c1.accept(20);
        c2.accept(20);

        //有参数有返回值
        Function<String, Person> f1 = name -> new Person(name);
        Function<String, Person> f2 = Person::new;
        f1.apply("jack ma");
        f2.apply("pony ma");
    }
}

执行结果:


构造方法引用结果.png

构造方法引用引用比较简单,根据代码很容易理解,就不再详细解释了。

相关文章

  • java8

    1.lambda表达式《java8 Lambda表达式简介》 《java8 lambda表达式,方法的引用以及构造...

  • JAVA 8 新特性

    1.JAVA 8 新特性 Lambda表达式:Lambda允许把函数作为一个方法的参数; 方法引用:方法引用提供了...

  • Java 8 - 方法引用

    Java 8 - 方法引用 1 Java 8-概述2 Java 8 - Lambda表达式3 Java 8 - 方...

  • Java 8:一文掌握 Lambda 表达式

    本文将介绍 Java 8 新增的 Lambda 表达式,包括 Lambda 表达式的常见用法以及方法引用的用法,并...

  • Java 8:一文掌握 Lambda 表达式

    本文将介绍 Java 8 新增的 Lambda 表达式,包括 Lambda 表达式的常见用法以及方法引用的用法,并...

  • Lambda 小记

    基本语法: 下面是Java lambda表达式的简单例子 方法引用 参考 静态方法引用 特定对象的方法引用 特定类...

  • Java 8 之方法引用 - Method References

    什么是方法引用 简单地说,就是一个 Lambda 表达式。在 Java 8 中,我们会使用 Lambda 表达式创...

  • Java 8、Java 9、Java 10 新特性

    Java8 Lambda 表达式:Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中。 方法引用 ...

  • JAVA8有哪些新特性

    java8新功能Lambda 表达式 - 增加函数处理能力到JAVA。 方法引用 - 引用函数由他们名称,而不是直...

  • 新特性5-方法引用

    方法引用使得开发者可以直接引用现存的方法、Java类的构造方法或者实例对象。方法引用和Lambda表达式配合使用,...

网友评论

      本文标题:Java Lambda表达式之方法引用

      本文链接:https://www.haomeiwen.com/subject/lujrictx.html