jdk8中的函数式接口

作者: 山东大葱哥 | 来源:发表于2019-06-19 09:55 被阅读16次

    熟悉JS的同学都知道在JS中,函数可以作为参数也可以作为返回值使用,这种编程方式就是函数式编程。而在Java 7及以前的版本中,是缺少这种支持的。
    在函数式编程思想下,允许把函数本身作为参数传入另一个函数,在Java 8中实现了函数式编程,通过使用函数式接口来“传递行为”的方式实现了这种函数式编程思想。
    当然也也依赖了JDK8中方法引用、Lambda表达式等新特性的支持。

    函数式接口

    通过@FunctionalInterface 注解进行标识,一个函数式接口需要满足两个条件:

    1. 必须是接口;
    2. 只有一个抽象方法(接口中的默认方法、静态方法都不算抽象方法);

    其实满足上述两个条件的接口及时不添加@FunctionalInterface 注解,也可以作为函数式接口来使用的。
    通过上述的两个条件很容易理解,函数式接口在使用时,就是将lambda表达式中的方法体或者方法引用等来替代唯一的抽象方法,因为抽象方法唯一,所以对方法的名称不敏感,可以随意定义方法名(方法引用)或者没有方法名(lambda表达式形式),但方法签名必须一致。

    JDK为了规范函数式接口的开发,也为了为函数式编程提供便利,提供了很多常用的函数式接口实现,这些实现的区别主要在于抽象方法的签名,如接收的参数个数、参数类型、返回值类型等。


    image.png

    以下的接口代码省略了非抽象方法

    Supplier<T>

    顾名思义,就是一个提供者接口,其中只有一个抽象方法get(),无参数,返回一个对象。Supplier函数式接口为“提供给定类型对象”的行为提供了一种抽象。

    @FunctionalInterface
    public interface Supplier<T> {
    
        /**
         * Gets a result.
         *
         * @return a result
         */
        T get();
    }
    

    Consumer<T>

    顾名思义,就是一个消费者接口,其中只有一个accept抽象方法,接受一个参数,没有返回值。实际编译后是通过LambdaMetafactory调用的Consumer的accept方法,而accept方法又是通过lambda表达式中的方法体实现的。

    @FunctionalInterface
    public interface Consumer<T> {
        /**
         * Performs this operation on the given argument.
         *
         * @param t the input argument
         */
        void accept(T t);
    }
    

    Consumer函数式接口为“消费给定对象”的行为提供了抽象,通过该函数式接口的accept方法可实现自定义的消费行为。

    Function<T,R>

    是一个函数接口,只有一个apply抽象方法,接受一个参数产生一个返回值。
    Function函数式接口接受一个T类型的参数,返回一个R类型的结果。该函数式接口是对有一个输入参数,产生一个输出结果的一类函数或行为的抽象。

    @FunctionalInterface
    public interface Function<T, R> {
        /**
         * Applies this function to the given argument.
         *
         * @param t the function argument
         * @return the function result
         */
        R apply(T t);
    }
    

    Predicate<T>

    是一个预测接口,只有test方法。
    Predicate函数式接口接受一个输入参数,返回boolean类型的结果。该函数式接口像特殊的Function<T,Boolean>函数式接口。

    @FunctionalInterface
    public interface Predicate<T> {
    
        /**
         * Evaluates this predicate on the given argument.
         *
         * @param t the input argument
         * @return {@code true} if the input argument matches the predicate,
         * otherwise {@code false}
         */
        boolean test(T t);
    }
    

    java.util.function包下其余接口

    其余接口都是上述类型的变体,主要是参数类型、参数数量、返回值的具化。

    相关文章

      网友评论

        本文标题:jdk8中的函数式接口

        本文链接:https://www.haomeiwen.com/subject/hhhfqctx.html