目录
简单一句话理解函数式编程,传统的方法调用我们都是传递参数,而函数式编程,传递的则是方法实现的过程。
1.目前Java中自带的函数式编程接口
1.线程类型
接口名 | 返回值/方法/参数 | 含义 |
Runnable | void run() | 定义多线程方法内容 |
Callable<V> | V call() | 有返回值的多线程方法 |
2.有参/无返回值 类型
接口名 | 返回值/方法/参数 | 含义 |
Consumer<T> | void accept(T t) | 接收一个参数,不返回值 |
BiConsumer<T,U> | void accept(T t,U u) | 接收两个参数,不返回值 |
ObjIntConsumer<T> | void accept(T t,int value) | 接收一个泛型参数和一个整形参数,不返回值 |
ObjDoubleConsumer<T> | void accept(T t,double value) | 接收一个泛型参数和一个双精度小数类型参数,不返回值 |
ObjLongConsumer<T> | void accept(T t,Long value) | 接收一个泛型参数和一个长整型的参数,不返回值 |
3.无参/有返回值 类型
接口名 | 返回值/方法/参数 | 含义 |
Supplier<T> | T get() | 不接受参数,返回一个泛型的参数 |
BooleanSupplier | boolean getAsBoolean() | 不接受参数,返回一个布尔参数 |
还有很多,不一一列举了...... |
4.有参/有返回值 类型
接口名 | 返回值/方法/参数 | 含义 |
Function<T, R> | R apply(T t) | 接收一个参数,返回另一种参数 |
Predicate<T> | boolean test(T t) | 接收一个参数,返回一个布尔值 |
这里也还有很多,就不一一列举了..... |
还有很多的函数式接口,具体可以参考java.util.function包下的内容
2.java中使用函数式编程的案例
1.ArrayList中的forEach方法
使用一下这个方法看看
打印结果:
这里的意思其实就是上面所说的,我们不是像传统的方法传递的是参数,传递的是一种方法的实现。从forEach的方法中不难看出,他是将List中的每一个元素放入accept的方法中的,而我们告诉了Consumer要去打印传入的每个参数。
2.再比如ArrayList中的replaceAll这个方法
可以看到,这里的逻辑是将List中的值经过变换,在赋给原来的引用,所以我们传入的实现就是改变的规则,如下:
结果:
3.Stream流
在Java.util.stream.Stream类下,我们可以看到大部分的方法都是用函数式编程实现的。
-
Stream<T> filter(Predicate<? super T> predicate)
-
<R> Stream<R> map(Function<? super T, ? extends R> mapper)
-
IntStream mapToInt(ToIntFunction<? super T> mapper)
-
LongStream mapToLong(ToLongFunction<? super T> mapper)
简单的实现:
这里通过少量的代码直接实现了对列表中所有的数字加10,过滤大于14的值,并组成一个新的List,并打印出来,我们来看看结果:
3.自定义函数式接口
自定义函数式接口需要满足个规则:
1.类型必须是接口。
2.接口里有且仅有一个抽象方法。
3.使用@FunctionalInterface标注接口。
4.自定义函数式接口的实现
当然,java提供的函数式接口,已经基本满足日常开发的需求了,合理的利用函数式编程,可以统一团队的开发规范,提高代码可读性,简化代码。