函数式接口(Functional Interface)是Java 8对一类特殊类型的接口的称呼。 这类接口只定义了唯一的抽象方法的接口,并且这类接口使用了@FunctionalInterface 进行注解。在jdk8中,引入了一个新的包java.util.function , 可以使java 8 的函数式编程变得更加简便。这个package中的接口大致分为了以下四类:
-
Function: 接收参数,并返回结果,主要方法 R apply(T t) -
Consumer: 接收参数,无返回结果, 主要方法为 void accept(T t) -
Supplier: 不接收参数,但返回结构,主要方法为 T get() -
Predicate: 接收参数,返回boolean值,主要方法为 boolean test(T t)
<img src="https://segmentfault.com/img/bVbhNvl/view" alt="preview" style="zoom:80%;" />
接口方法
Function方法
接收单个参数
Interface | functional method | 说明 |
---|
Function<T,R> | R apply(T t) | 接收参数类型为T,返回参数类型为R | IntFunction<R> | R apply(int value) | 以下三个接口,指定了接收参数类型,返回参数类型为泛型R | LongFunction<R> | R apply(long value) | | Double<R> | R apply(double value) | | ToIntFunction<T> | int applyAsInt(T value) | 以下三个接口,指定了返回参数类型,接收参数类型为泛型T | ToLongFunction<T> | long applyAsLong(T value) | | ToDoubleFunction<T> | double applyAsDouble(T value) | | IntToLongFunction | long applyAsLong(int value) | 以下六个接口,既指定了接收参数类型,也指定了返回参数类型 | IntToDoubleFunction | double applyAsLong(int value) | | LongToIntFunction | int applyAsLong(long value) | | LongToDoubleFunction | double applyAsLong(long value) | | DoubleToIntFunction | int applyAsLong(double value) | | DoubleToLongFunction | long applyAsLong(double value) | | UnaryOperator<T> | T apply(T t) | 特殊的Function,接收参数类型和返回参数类型一样 | IntUnaryOperator | int applyAsInt(int left, int right) | 以下三个接口,指定了接收参数和返回参数类型,并且都一样 | LongUnaryOperator | long applyAsInt(long left, long right) | | DoubleUnaryOperator | double applyAsInt(double left, double right) | |
接收两个参数
interface | functional method | 说明 |
---|
BiFunction<T,U,R> | R apply(T t, U u) | 接收两个参数的Function | ToIntBiFunction<T,U> | int applyAsInt(T t, U u) | 以下三个接口,指定了返回参数类型,接收参数类型分别为泛型T, U | ToLongBiFunction<T,U> | long applyAsLong(T t, U u) | | ToDoubleBiFunction<T,U> | double appleyAsDouble(T t, U u) | | BinaryOperator<T> | T apply(T t, T u) | 特殊的BiFunction, 接收参数和返回参数类型一样 | IntBinaryOperator | int applyAsInt(int left, int right) | | LongBinaryOperator | long applyAsInt(long left, long right) | | DoubleBinaryOperator | double applyAsInt(double left, double right) | |
Consumer方法
接收一个参数
interface | functional method | 说明 |
---|
Consumer<T> | void accept(T t) | 接收一个泛型参数,无返回值 | IntConsumer | void accept(int value) | 以下三个类,接收一个指定类型的参数 | LongConsumer | void accept(long value) | | DoubleConsumer | void accept(double value) | |
接收两个参数
interface | functional method | 说明 |
---|
BiConsumer<T,U> | void accept(T t, U u) | 接收两个泛型参数 | ObjIntConsumer<T> | void accept(T t, int value) | 以下三个类,接收一个泛型参数,一个指定类型的参数 | ObjLongConsumer<T> | void accept(T t, long value) | | ObjDoubleConsumer<T> | void accept(T t, double value) | |
Supplier方法
interface | functional method | 说明 |
---|
Supplier<T> | T get() | 返回类型为泛型T | BooleanSupplier | boolean getAsBoolean() | 以下三个接口,返回指定类型 | IntSupplier | int getAsInt() | | LongSupplier | long getAsLong() | | DoubleSupplier | double getAsDouble() | |
Predicate方法
根据接收参数进行断言,返回boolean类型
interface | functional method | 说明 |
---|
Predicate<T> | boolean test(T t) | 接收一个泛型参数 | IntPredicate | boolean test(int value) | 以下三个接口,接收指定类型的参数 | LongPredicate | boolean test(long value) | | DoublePredicate | boolean test(double value) | | BiPredicate<T,U> | boolean test(T t, U u) | 接收两个泛型参数,分别为T,U |
实现函数式接口的三种方法
编写实现类
?public class MyFunction implements Function <Integer, Integer>{
? ? ?@Override
? ? ?public Integer apply(Integer integer) {
? ? ? ? ?return null;
? ? }
?}
匿名内部类
new Function<Integer, Integer>() {
? ? ?@Override
? ? ?public Integer apply(Integer integer) {
? ? ? ? ?return null;
? ? }
?};
lambda表达式
IntFunction<Integer> integerIntFunction = (int a) -> {
? ? ?return a;
?};
lambda表达式就是为了优化匿名内部类而生
Function功能型函数式接口
Function接口 接受一个输入参数T,返回一个结果R
@FunctionalInterface
?public interface Function<T, R> {
??
? ? ?// 接受输入参数,对输入执行所需操作后 返回一个结果
? ? ?R apply(T t);
??
? ? ?// 返回一个 先执行before函数对象apply方法,再执行当前函数对象apply方法的 函数对象。
? ? ?default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
? ? ? ? ?Objects.requireNonNull(before);
? ? ? ? ?return (V v) -> apply(before.apply(v));
? ? }
??
? ? // 返回一个 先执行当前函数对象apply方法, 再执行after函数对象apply方法的 函数对象。
? ? ?default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
? ? ? ? ?Objects.requireNonNull(after);
? ? ? ? ?return (T t) -> after.apply(apply(t));
? ? }
??
? // 返回一个执行了apply()方法之后只会返回输入参数的函数对象。
? ? ?static <T> Function<T, T> identity() {
? ? ? ? ?return t -> t;
? ? }
?// lambda表达式
?IntFunction<Integer> integerIntFunction = (int a) -> a+10;
??
?// 匿名内部类
?IntFunction<Integer> intFunction = new IntFunction<Integer>() {
? ? ?@Override
? ? ?public Integer apply(int value) {
? ? ? ? ?return value + 20;
? ? }
?};
?System.out.println(integerIntFunction.apply(10)); // 20
?System.out.println(intFunction.apply(10)); // 30
?// andThen方法使用
?public static Integer andThenTest(int value, Function<Integer, Integer> f1, Function<Integer, Integer> f2){
? ? ?return f1.andThen(f2).apply(value);
?}
??
?public static void main(String[] args) {
? ? ?System.out.println(andThenTest(10, val -> val + 10, val -> val + 20)); // 40
?}
Consumer消费型函数式接口
代表了 接受一个输入参数并且无返回的操作
?@FunctionalInterface
?public interface Consumer<T> {
? ? ?
? ? ?void accept(T t);
??
? ? ?// 代表一个组合函数,先执行当前函数,再执行after函数,如果执行当前函数抛出异常,不会执行after函数,如果执行after函数抛出异常,则异常会传递给调用者
? ? ?default Consumer<T> andThen(Consumer<? super T> after) {
? ? ? ? ?Objects.requireNonNull(after);
? ? ? ? ?return (T t) -> { accept(t); after.accept(t); };
? ? }
?}
Consumer<String> consumer = s -> System.out.println(s + " consumer test");
??
?Consumer<String> consumer = new Consumer<String>() {
? ? ?@Override
? ? ?public void accept(String s) {
? ? ? ? ?System.out.println(s + " consumer test");
? ? }
?};
?consumer.accept("one"); // one consumer test
Supplier供给型函数式接口
无参数,返回一个结果
?@FunctionalInterface
?public interface Supplier<T> {
? ? ?T get();
?}
?Supplier<String> supplier = () -> "supplier test msg";
??
?Supplier<String> supplier = new Supplier<String>() {
? ? ?@Override
? ? ?public String get() {
? ? ? ? ?return "supplier test msg";
? ? }
?};
??
?System.out.println(supplier.get()); // supplier test msg
?System.out.println(supplier.get()); // supplier test msg
Predicate断言型函数式接口
接受一个输入参数,返回一个布尔值结果
?@FunctionalInterface
?public interface Predicate<T> {
??
? ? ?// 通过test方法进行判断,如果成功,返回true,如果失败返回false
? ? ?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);
? ? }
??
? ? ?// 通过Objects的equals判断两个对象是否equals
? ? ?static <T> Predicate<T> isEqual(Object targetRef) {
? ? ? ? ?return (null == targetRef)
? ? ? ? ? ? ? ? ?? Objects::isNull
? ? ? ? ? ? ? ? : object -> targetRef.equals(object);
? ? }
?}
Predicate<Integer> predicate = integer -> integer == 3;
??
?Predicate<Integer> predicate = new Predicate<Integer>() {
? ? ?@Override
? ? ?public boolean test(Integer integer) {
? ? ? ? ?return integer == 3;
? ? }
?};
??
?System.out.println(predicate.test(3)); // true
?System.out.println(predicate.test(4)); // false
?public static void eval(List<Integer> list, Predicate<Integer> predicate) {
? ? ? ? ?for (Integer n : list) {
? ? ? ? ? ? ?if (predicate.test(n)) {
? ? ? ? ? ? ? ? ?System.out.print(n + " ");
? ? ? ? ? ? }
? ? ? ? }
? ? }
??
? ? ?public static void main(String args[]) {
? ? ? ? ?List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
??
? ? ? ? ?// Predicate<Integer> predicate = n -> true
? ? ? ? ?// n 是一个参数传递到 Predicate 接口的 test 方法
? ? ? ? ?// n 如果存在则 test 方法返回 true
? ? ? ? ?System.out.println("输出所有数据:");
??
? ? ? ? ?// 传递参数 n
? ? ? ? ?eval(list, n -> true);
??
? ? ? ? ?// Predicate<Integer> predicate1 = n -> n%2 == 0
? ? ? ? ?// n 是一个参数传递到 Predicate 接口的 test 方法
? ? ? ? ?// 如果 n%2 为 0 test 方法返回 true
??
? ? ? ? ?System.out.println("\n输出所有偶数:");
? ? ? ? ?eval(list, n -> n % 2 == 0);
??
? ? ? ? ?// Predicate<Integer> predicate2 = n -> n > 3
? ? ? ? ?// n 是一个参数传递到 Predicate 接口的 test 方法
? ? ? ? ?// 如果 n 大于 3 test 方法返回 true
??
? ? ? ? ?System.out.println("\n输出大于 3 的所有数字:");
? ? ? ? ?eval(list, n -> n > 3);
? ? }
?输出所有数据:
?1 2 3 4 5 6 7 8 9
?输出所有偶数:
?2 4 6 8
?输出大于 3 的所有数字:
?4 5 6 7 8 9
?//需求:使用Predicat接口作为方法的参数,实现对一个字符的长度进行判断
?public static boolean checkStr(String s, Predicate<String> predicate){
? ? ?return predicate.test(s);
?}
??
?public static void main(String[] args) {
? ? ?boolean result = checkStr("zha", (str) -> {
? ? ? ? ?return str.length() > 5;
? ? });
? ? ?System.out.println(result);
?}
?//需求:判断一个字符串的长度是否大于5,并且判断该字符串中是否包含a
?/*分析:1.与 操作,可以使用&& 或使用and()方法去实现
? ? ? ? ? ? 2.我们可以传递两个Predicate类型的参数,
? ? ? ? ? ? ?第一个参数用来判断字符串的长度是否大于5
? ? ? ? ? ? ?第一个参数用来判断该字符串中是否包含a
? ? ?*/
?public static boolean checkString(String s,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Predicate<String> predicate1,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Predicate<String> predicate2){
? ? ?//predicate1.test(s)&&predicate2.test(s);
? ? ?return predicate1.and(predicate2).test(s);
?}
?public static void main(String[] args) {
? ? ?boolean b = checkString("zha",(s)->{
? ? ? ? ?return s.length()>5;
? ? },(s)->{
? ? ? ? ?int i = s.indexOf("a");
? ? ? ? ?if(i>0){
? ? ? ? ? ? ?return true;
? ? ? ? }else{
? ? ? ? ? ? ?return false;
? ? ? ? }
? ? });
? ? ?System.out.println(b);
?}
|