版权声明:转载自 6点A君 的博文(https://blog.csdn.net/anLA_/article/details/78191494)

Java8增加了函数式编程这一新特性,我这几天也在慢慢学习,现在就来讲讲Function接口。

何为Function接口?

在java8以后的接口可以有接口方法的默认实现了,如下所示,Function接口主要代码及个人整理注释:

/**
 * 代表这一个方法,能够接受参数,并且返回一个结果
 * @since 1.8
 */
@FunctionalInterface
public interface Function<T, R> {
    /**
     * 将参数赋予给相应方法
     * 
     * @param t
     * @return
     */
    R apply(T t);

    /**
     * 先执行参数(即也是一个Function)的,再执行调用者(同样是一个Function)
     */
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }
    /**
     * 先执行调用者,再执行参数,和compose相反。
     */
    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类的具体代码,里面有四个方法,分别是applycomposeandThenidentity,具体的方法注释卸载代码里面了,主要我想在这里敲敲黑板,就是他们的返回值,apply是R,也就是代表最终返回结果,其他三个都是返回一个Function,也就是他们借个是可以进行更多的后层嵌套的,类似于建造者模式去生成类的过程。

具体例子

    public static void main(String[] args) {
        Function<Integer, Integer> times2 = i -> i*2;
        Function<Integer, Integer> squared = i -> i*i;
        
        System.out.println(times2.apply(4));
        
        System.out.println(squared.apply(4));
        
		//32                先4×4然后16×2,先执行apply(4),在times2的apply(16),先执行参数,再执行调用者。
        System.out.println(times2.compose(squared).apply(4));  
        
        //64               先4×2,然后8×8,先执行times2的函数,在执行squared的函数。
        System.out.println(times2.andThen(squared).apply(4));  
        
		 //16
        System.out.println(Function.identity().compose(squared).apply(4));  
    }

代码里面有点注释,当然输出结果为:

8
16
32
64
16

前两个输出比较容易理解,就是把参数值赋值到方法里面,再由apply返回的结果输出即可。
主要就是第3,4个的compose和andThen,由于代码里面是很简单两个数学计算,先说明大概流程,估计推一推就懂了。

在compose里面,先执行squared的apply(4)方法,然后再把结果给times2让他去执行16×2的方法。

而andThen恰恰相反,由英文来理解,先后顺序,即先执行times2的apply方法,再把结果执行squared的apply方法。

这样,就能得到最终的结果。

而在最后一个输出中,虽然有compose方法,但是前一个的Function.identity并没有任何方法,因为identity仅仅是返回一个方法,所以也就执行了squared这一个方法而已。

通过上文的分析,大概可以理解Function这个类了,就是一个方法,有种c++里面函数指针的感觉,一个变量可以指向一个方法,并且可以把两个方法组合起来使用(使用compose和andThen),而可以通过identity这个静态方法来获取当前执行的方法。

 

刚开始写博文,有不足之处请指出;觉得文章实用,请在右上方点个赞


GitHub 加速计划 / compose / compose
33.27 K
5.15 K
下载
compose - Docker Compose是一个用于定义和运行多容器Docker应用程序的工具,通过Compose文件格式简化应用部署过程。
最近提交(Master分支:2 个月前 )
5e3a0953 full diff: https://github.com/docker/cli/compare/v27.4.0-rc.1...8d1bacae3e49ed1d096eede8eef4ae851d7f2eae Signed-off-by: Sebastiaan van Stijn <github@gone.nl> 1 天前
a2a3eb72 - full diff: https://github.com/docker/cli/compare/cb3048fbebb1...v27.4.0-rc.1 Signed-off-by: Sebastiaan van Stijn <github@gone.nl> 1 天前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐