java8函数式接口

java8函数式接口

引言

函数式接口是java8的新特性,通过注解@FunctionalInterface保证接口满足函数式接口的定义。结合lamda表达式可以帮助我们写出逻辑清晰优雅的代码。jdk中包含了很多预定义的函数式接口,它们都在java.util.function;包中,本篇主要分析该包的接口定义和日常使用。

什么是函数式接口?
函数式接口指的是只含有一个抽象方法的接口,该类型的lamda表达式都映射到此方法。

Consumer

1
2
3
4
5
6
7
8
9
10
@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); };
}
}

用途:表示只有一个参数,没有返回值的函数。T是参数类型。andThen是默认方法,也是java8中的新特性,它可以在附加上一个Consumer,这样就能对当前参数”消费”两次。

变体 表示函数
BiConsumer 两个参数,没有返回值
DoubleConsumer,IntConsumer,LongConsumer 一个double,int,long参数,没有返回值
ObjDoubleConsumer,ObjIntConsumer,ObjLongConsumer BiConsumer的变体,一个double,int,long参数,一个object参数

Function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
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;
}
}

用途:表示一个参数,产生一个返回值的函数。T是参数类型,R是返回类型。compose可以在apply之前插入一个处理,这个处理参数类型是V,返回类型是TandThen可以在apply之后插入一个处理,这个处理的参数类型是R,返回类型是V

变体 表示函数
BiFunction 两个参数,一个返回值
DoubleFunction,IntFunction,LongFunction 一个double,int,long参数,一个返回值
DoubleToIntFunction,DoubleToLongFunction 类型转换
IntToDoubleFunction,IntToLongFunction 类型转换
LongToDoubleFunction,LongToIntFunction 类型转换
ToDoubleBiFunction,ToIntBiFunction,ToLongBiFunction 两个参数,返回double
ToDoubleFunction,ToIntFunction,ToLongFunction 一个参数,返回double

Predicate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@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);
}
}

用途:表示只有一个参数,返回值是boolean类型的函数。and新增的条件与当前测试条件结果“与”操作。negate取反,or新增的条件与当前测试条件结果“或”操作。

变体 表示的函数
BiPredicate 有两个参数,返回boolean类型
DoublePredicate,IntPredicate,LongPredicate 参数是double,返回boolean类型

Supplier

1
2
3
4
@FunctionalInterface
public interface Supplier<T> {
T get();
}

用途:表示没有参数,有返回值的函数。

变体 表示的函数
BooleanSupplier 没有参数,返回值是boolean
DoubleSupplier,IntSupplier,LongSupplier 没有参数,返回值是double

UnaryOperator

1
2
3
4
5
6
7
@FunctionalInterface
public interface UnaryOperator<T> extends Function<T, T> {
static <T> UnaryOperator<T> identity() {
return t -> t;
}
}

用途:表示一个参数,返回值与参数同类型的函数

变体 表示函数
DoubleUnaryOperator,IntUnaryOperator,LongUnaryOperator 参数和返回值都是double类型

BinaryOperator

1
2
3
4
5
6
7
8
9
10
11
12
13
@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T,T,T> {
public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
}
public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
}
}

用途:表示两个同类型参数,返回值与参数同类型的函数

变体 表示函数
DoubleBinaryOperator,IntBinaryOperator,LongBinaryOperator 两个double参数,返回值也是double类型

小栗子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.zhaoyangwoo.utils;
import java.util.function.Function;
/**
* Created by john on 16/10/25.
*/
public class functionalTest {
public static <T, R, V> R getString(Function<T, R> fi, Function<V, T> fi2, V argument) {
return fi.compose(fi2).apply(argument);
}
public static void main(String[] args) {
Function<Integer, String> f1 = Object::toString;
Function<String, Integer> f2 = Integer::new;
System.out.println(getString(f1, f2, "3"));
}
}

参考

浅谈Java 8的函数式编程

作者: wuzhaoyang(John)
出处: http://wuzhaoyang.me/
因为作者水平有限,无法保证每句话都是对的,但能保证不复制粘贴,每句话经过推敲。希望能表达自己对于技术的态度,做一名优秀的软件工程师。