FP in java8
java函数式,带着脚镣跳舞
Java8
Java没有对函数变量的原生支持,为了吸收FP范式并且保持向下兼容,在Java8中引入了函数式接口的概念(Functional Interface,指那些有且只有一个抽象方法的的接口,但还可以有其他的默认方法),通过将函数包裹在接口的实现类中(作为接口抽象方法的实现)进行传递。在Java8之前这种效果是通过匿名类的方法来实现的,Java8引入的lambda表达式极大地简化了函数式接口的书写,可以直接将一个lambda表达式赋值给类型匹配的函数式接口,将直接内联实现其内部的唯一的抽象方法。
Function<Integer, Function<Integer, Function<Integer, Integer>>> f =
x -> y -> z -> x + y + z;
Integer added = f.apply(1).apply(2).apply(3);
System.out.println(added);
但是如果函数是递归的,则不能直接使用lambda表达式赋值,因为Java的lambda表达式不支持自引用,只能通过匿名类的方式来实现
Function<BigInteger, BigInteger> factorial = new Function<>() {
@Override
public BigInteger apply(BigInteger n) {
if (n.equals(BigInteger.ONE)) {
return BigInteger.ONE;
}
return n.multiply(apply(n.subtract(BigInteger.ONE)));
}
};
factorial.apply(BigInteger.valueOf(5));
接下来让我们看看Java官方提供的函数式接口
Function<T,R>
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
//NPE if before is null
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
//NPE if after is null
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;
}
}
Function接口是一种映射,apply()函数签名是T->R,接受一个泛型T的参数,返回一个R类型的参数
通过default方法compose()和andThen()可以实现Function的组合
static方法identity()是一个返回自身的映射,单位映射子
对于Function<T,T>还有一个新的接口UnaryOperator
@FunctionalInterface
public interface UnaryOperator<T> extends Function<T, T> {
static <T> UnaryOperator<T> identity() {
return t -> t;
}
}
对于两个参数的版本有接口BiFunction<T,U,R****> (T,U)->R
@FunctionalInterface
public interface BiFunction<T, U, R> {
R apply(T t, U u);
//NPE if after is null
default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t, U u) -> after.apply(apply(t, u));
}
}
同样的对于(T,U)->R 也有一个特化版的函数式接口BinaryOperator
@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T,T,T> {
//NPE if the argument is null
public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
}
//NPE if the argument is null
public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
}
}
Java开发人员并没有定义三个参数的函数式接口,但我们可以自己定义,注意deafult方法完全可以省略
或者使用**柯里化**来减少参数
import java.util.Objects;
import java.util.function.Function;
@FunctionalInterface
public interface TriFunction<T, U, E, R> {
R apply(T t, U u, E e);
default <V> TriFunction<T, U, E, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t, U u, E e) -> after.apply(apply(t, u, e));
}
}
Supplier
@FunctionalInterface
public interface Supplier<T> {
T get();
}
Supplier
通常用它作为数据提供者
Consumer
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
//NPE if after is null
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
Consumer
还有一个default方法then()来和其他的Consumer
通常用它对数据进行终结操作
还有一个接受两个参数的BiConsumer<T,U> (T,U)->void
Predicate
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
// NPE if other is null
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);
}
// NPE if other is null
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);
}
//since 11
//NPE if target is null
@SuppressWarnings("unchecked")
static <T> Predicate<T> not(Predicate<? super T> target) {
Objects.requireNonNull(target);
return (Predicate<T>)target.negate();
}
}
Predicate
default方法and()、or()、negate()能实现谓词Predicate
还有接受两个参数的谓词函数式接口**BiPredicate<T,U> **(T,U)->boolean
Other Functional Interface
还有一些特化的函数式接口
以下占位符均指代Int/Long/Double三种基本数据类型
Function<T,R>
- XXXFunction
(XXX)->R - ToXXXFunction
(T)->XXX - XXXToYYYFunction (XXX)->YYY
- XXXUnaryOperator (XXX)->XXX
- ToXXXBiFunction<T,U> (T,U)->XXX
- XXXBinaryFunction (XXX,XXX)->XXX
Supplier
- XXXSupplier+BooleanSupplier void ->XXX/boolean
Consumer
- XXXConsumer (XXX)->void
- ObjXXXConsumer
(T,XXX)->void
Predicate
- XXXPredicate (XXX)->boolean
Comparator
用于创建比较器/比较器链来进行排序 ,函数签名是(T,T)->int ,通常使用其静态方法来构造比较器
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}
//NullPointerException if the argument is null
default Comparator<T> thenComparing(Comparator<? super T> other) {
Objects.requireNonNull(other);
return (Comparator<T> & Serializable) (c1, c2) -> {
int res = compare(c1, c2);
return (res != 0) ? res : other.compare(c1, c2);
};
}
default <U> Comparator<T> thenComparing(
Function<? super T, ? extends U> keyExtractor,
Comparator<? super U> keyComparator)
{
return thenComparing(comparing(keyExtractor, keyComparator));
}
default <U extends Comparable<? super U>> Comparator<T> thenComparing(
Function<? super T, ? extends U> keyExtractor)
{
return thenComparing(comparing(keyExtractor));
}
default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) {
return thenComparing(comparingInt(keyExtractor));
}
default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) {
return thenComparing(comparingLong(keyExtractor));
}
default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) {
return thenComparing(comparingDouble(keyExtractor));
}
public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
return Collections.reverseOrder();
}
@SuppressWarnings("unchecked")
public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
}
public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) {
return new Comparators.NullComparator<>(true, comparator);
}
public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) {
return new Comparators.NullComparator<>(false, comparator);
}
//NullPointerException if the argument is null
public static <T, U> Comparator<T> comparing(
Function<? super T, ? extends U> keyExtractor,
Comparator<? super U> keyComparator)
{
Objects.requireNonNull(keyExtractor);
Objects.requireNonNull(keyComparator);
return (Comparator<T> & Serializable)
(c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),
keyExtractor.apply(c2));
}
//NullPointerException if the argument is null
public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
Function<? super T, ? extends U> keyExtractor)
{
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}
//NullPointerException if the argument is null
public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
}
//NullPointerException if the argument is null
public static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));
}
//NullPointerException if the argument is null
public static<T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
}
}
Runnable
实现线程对象的一种方式
void->void
@FunctionalInterface
public interface Runnable {
/**
* Runs this operation.
*/
void run();
}