一次性搞定Function接口

本文带你快速、详细的了解java8的核心四大接口之一的Function接口,从源码到demo了解此接口,让你享受它的妙处。

 java8出现了四大接口:消费型,供给型,函数式,断言式

其中Function接口有四个方法:以下依依介绍:

@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;
    }
}

(1)apply:

创建一个函数式接口,你需要制订两个泛型参数(姑且这么叫吧)。第一个泛型参数是apply传入的参数类型,第二个是返回参数类型。

你创建了一个Function实现类(用的匿名内部内):你可以通过调用函数的apply来使用该函数。

        //Function f= (Function<String, String>) s -> "我想说"+s; lambda表达式
        Function f=new Function<String, String>() {
            @Override
            public String apply(String s) {
                return "我想说"+s;
            }
        };
        String res=(String) f.apply("lbwnb");
        System.out.println(res);

(2)compose:

你看了源码就知道这玩意儿也是返回一个Function:那这玩意儿有啥用呢:

它允许接受一个Function,返回一个新的Function,他源码也是用的lambda表达式,基础薄弱的同学可能看不懂,我就重新写一下(我写的看不懂也是正常的,只是让你们知道个流程):

        Function f1=new Function<Integer, Integer>() {
            @Override
            public Integer apply(Integer n) {
                return n+1;
            }

            @Override
            public <V> Function<V, Integer> compose(Function<? super V, ? extends   Integer> before) {
                Function<Integer,Integer> that=this;  //保存this的指向
                return new Function<V, Integer>() {
                    @Override
                    public Integer apply(V v) {
                        Integer tmp=before.apply(v);  //传入函数先调用
                        return that.apply(tmp);        //返回外部this调用的apply的值
                    }
                };
            }
        };

 然后我们就可以开始我们的使用流程

Function f1=new Function<Integer, Integer>() {
            @Override
            public Integer apply(Integer n) {
                return n+1;
            }
        };
        Function f2=new Function<Integer, Integer>() {
            @Override
            public Integer apply(Integer n) {
                return n*n;
            }
        };
        //先执将2的值传f2的方法执行完过后,再将返回值作为f1的apply参数
        //所以先是2*2=4 再4+1=5
        Integer res=(Integer) f1.compose(f2).apply(2);
        System.out.println(res);

使用这个函数就可以嵌套的控制函数的执行顺序,举个简单的例子(可能不完全恰当哈):a操作依赖于b,b依赖于c,c依赖于d,所以你调用函数的顺序是d,c,b,a。这样有个啥子问题呢,你这样代码量少还好,要是逻辑啥的强了,代码多了,你就不能很好的确定他们的调用顺序了,使用函数式接口,就做到了一个串联,环环相扣,所有的执行操作,中间产生的数据都不会暴露给外部,外部无法修改,读取(也算是保证了数据流的安全)。我们只管调用。你无需还要中间变量进行接受,并且你不能保证中间产生的数据是否会被修改。这只是衍生出的一小部分使用而已。

 (3)andThen

这个方法于上一个相反,是先调用this指向的apply,再将返回值给传入的函数实现类的apply

       Function f1=new Function<Integer, Integer>() {
            @Override
            public Integer apply(Integer n) {
                return n + 1;
            }
        };
        Function f2=new Function<Integer, Integer>() {
            @Override
            public Integer apply(Integer n) {
                return n*n;
            }
        };
        Integer res=(Integer) f1.andThen(f2).apply(2);
        System.out.println(res);

 res的值显然就是9,   2+1=3;3*3=9

调用顺序而已

(4)identify

        最后这个是一个静态方法,它也是返回一个Function函数,这个函数的默认实现  你看源码就知道它是直接返回你传入的那个值,就是默认apply实现:t->t  这样;有啥大用我不知道,但它确实可以快速生成一个Function实现类,用于你需要一个Function实现类,而你不想它有啥操作,直接返回原来的值就行。

//1
System.out.println(Function.<Integer>identity().apply(1));

        这是本人学习java4个月以来第一篇博客,要是喜欢就关注一下,我有时间会持续更新的~

有错欢迎指正,有需要讲解的可以评论告诉我,说不定下一次我就更新了。

 

 

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值