一起来学Java8(一)——函数式编程

所谓的函数式编程就是把函数名字当做值进行传递,然后接收方拿到这个函数名进行调用。

首先来看下JavaScript如何进行函数调用

 1var Person = {
 2    sayHello: function(name) {
 3        alert('hello ' + name);
 4    }
 5};
 6
 7function work(fn) {
 8    fn('Jim');
 9}
10
11work(Person.sayHello); // hello Jim
复制代码

在这个例子中,sayHello函数被当做一个参数传递到另一个work函数当中,然后work调用给定的函数。

Java8中的函数式编程

在Java中,充当函数的角色是类中方法,在本篇文章当中提到的函数泛指方法。

接下来看下Java8中一个简单的函数式编程例子:

 1import java.util.function.Consumer;
 2
 3class Person {
 4    public static void sayHello(String name) {
 5        System.out.println("hello " + name);
 6    }
 7}
 8
 9public class TestPerson {
10
11    public static void main(String[] args) {
12        work(Person::sayHello); // hello Jim
13    }
14
15    public static void work(Consumer<String> consumer) {
16        consumer.accept("Jim");
17    }
18}
复制代码

从这个例子中可以看到,Java8传递函数的方式跟JavaScript不一样,在Java8当中传递函数的方式是:方法引用::方法名称,如:String.valueOf,String.toString。接收参数Consumer可以先不用去了解,后面会讲到。

为了接收传递过来的函数引用,Java设计者提出了一个函数式接口的概念

函数式接口

函数式接口定义:一个接口里面只有一个抽象方法。

如下面几个接口都是函数式接口:

  • Consumer

  • Supplier

  • Runnable

  • Callable

查看Runnable类的源码可以发现,在类上方定义了一个@FunctionalInterface注解

1@FunctionalInterface
2public interface Runnable {
3    public abstract void run();
4}
复制代码
  • @FunctionalInterface注解的作用:

当做一个标记使用,标记当前接口是一个函数式接口,如果你的接口有多个抽象方法或没有抽象方法,那么会编译报错。它的作用有点类似于@override注解,有辅助作用,但不是必须的。如果你想设计一个函数式接口,那么最好把它加上。

 1// 编译不通过,必须要有一个抽象方法
 2@FunctionalInterface
 3public interface InterfaceA {
 4
 5}
 6
 7// 编译通过,只有一个抽象方法
 8@FunctionalInterface
 9public interface InterfaceB {
10    void run();
11}
12
13// 编译不通过,只能有一个抽象方法
14@FunctionalInterface
15public interface InterfaceC {
16    void run();
17
18    void run2();
19}
20
21// 编译通过,run2是默认方法,并不是抽象方法
22// 在这里只有一个run抽象方法
23@FunctionalInterface
24public interface InterfaceD {
25    void run();
26
27    default void run2() {};
28}
复制代码

在例子InterfaceD中涉及到了接口默认方法default void run2() {};,这里略过不讲,后续文章中会有提到。

我们可以实现一个自定义的函数式接口,替代Consumer

 1// 自定义函数式接口
 2@FunctionalInterface
 3public interface FunctionCaller<T> {
 4    void call(T t);
 5}
 6
 7public class TestPerson2 {
 8
 9    public static void main(String[] args) {
10        work(Person::sayHello);
11    }
12
13    public static void work(FunctionCaller<String> caller) {
14        caller.call("Jim");
15    }
16}
复制代码

小结

本篇主要讲解了在Java8下如何进行函数式编程,以及如何定义和使用一个函数式接口。

原文 

https://juejin.im/post/5e7f21626fb9a03c46491f0b

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 一起来学Java8(一)——函数式编程

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址