什么是函数式编程
函数式编程是一种编程范式,是一种如何编写程序的方法论。 举个简单例子:
代码语言:javascript复制int a =10;
int b = 15;
int c = 2;
int sum = a b;
int quadrature = sum * c;
这样的方式属于命令式编程,关心的是解决问题的步骤。
函数编程
代码语言:javascript复制Math.multiplyExact(Math.addExact(a,b),c);
特点:
- 函数是“一等公民” 函数是和其他数据类型一样可以赋值给变量,可以作为方法参数,返回值。
- 只用“表达式”,不用“语句”
- 没有副作用
- 不修改状态
- 引用透明
优点:
1、减少键盘的开销
2、便于理解 —— 例如:merge([1,2],[3,4]).sort().search("2")
3、方便单元测试 ——针对函数不涉及外部状态变化,参数固定返回结果也相同。
4、不用考虑死锁的问题 —— 不修改变量
Java8 新增的函数式接口
分四种: 先看下源码的介绍
- Function 接收一个T类型参数,返回R类型。
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
//生成参数类型和before 一样
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
//生成返回类型和after一样
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
- Consumer 接收一个T类型的参数,没有返回值,andThen后面可以在追加一个Consumer
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
- Predicate 条件判断接口,接受一个T类型的参数,返回Boolean类型,and/or/negate 分别对应逻辑与、或、非。isEqual
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
- Supplier
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
Demo
代码语言:javascript复制Function
Function<Integer, Integer> functionA = n -> n 1;
Function<Integer, Integer> functionB = n -> n * n;
//返回 3
functionA.apply(2);
//返回 4
functionB.apply(2);
//返回 5 等价于 functionA.apply(functionB.apply(2));
functionA.compose(functionB).apply(2);
//返回 9 等价于 functionB.apply(functionA.apply(2));
functionA.andThen(functionB).apply(2);
Predicate
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
//打印 3的倍数
filter(list, n -> n % 3 == 0);
public static void filter(List<Integer> list, Predicate<Integer> predicate) {
Consumer<Integer> consumer = i -> {
if (predicate.test(i)) {
System.out.println(i);
}
};
list.forEach(consumer);
}
Consumer
Consumer consumer = n -> System.out.println(n);
//打印 "hello"
consumer.accept("hello");
//打印3个hello
consumer.andThen(consumer).andThen(consumer).accept("hello");
Supplier
Supplier supplier = Object::new;
//get 调用才会new Object
supplier.get();
function下还有许多functionInterface ,具体用法可以深入了解下。
image.png
其中@FunctionalInterface 只是注明这是一个Function 接口,且加改注解的接口有且必须只有一个抽象方法,但是对于这个注解不是强制的。