Java 8 辣么大(lambda)表达式不慌之-----(一)Function

Java 8 辣么大(lambda)表达式不慌之一—–Function

用java 8 的辣么大(lambda)表达式的时候肯定用到过Function<T, R> 这个东西,但是在我刚刚用的时候他的写法让我很别扭,很不适应,所以就不得不去打开他的源码看看他到底儿是个什么鬼。
这里写图片描述
看起来这个接口挺简单的,下面总共也就4个接口俩default、一static。
先看看接口说明:Represents a function that accepts one argument and produces a result. 接收一个参数返回一个结果,就这么简单,就像y=f(x)这么简单。f(x)=x+1,写成java代码就是:

Function<Integer,Integer> myFun = (x)->{
     return x+1;
};

再看定义的方法:

第一个方法R apply(T t);
    /**
     * Applies this function to the given argument.
     *
     * @param t the function argument
     * @return the function result
     */
    R apply(T t);

这个方法简单,就是用给的参数去执行这个方法,得到结果(有没有感觉跟那个invoke有点像的感觉?)。拿上面的举例子:f(x)=x+1 所以 y=x+1,如果x=1那么执行一下就是y=1+1。写成java代码就是:

// myFun就是上面定义的myFUn
Integer applyResult = myFun.apply(1); // applyResult =2
第二个方法Function<V, R> compose(Function<? super V, ? extends T> before)
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
    Objects.requireNonNull(before);
    return (V v) -> apply(before.apply(v));
}

这个方法的返回值还是一个Function,参数也是一个Function。从方法的注释,或者方法的实现可以看出来(通常我们看到一个方法,先看注释,大概就知道方法是做什么的,怎么使用,然后再看实现与注释相佐证)这个方法是先apply参数里面的Function然后返回一个Function。举个栗子,就是现在有2个函数:y=f(x),z=f(x),所以如果2个函数y=x+1,z=x*3那么此处就是y=(x*3)+1。写成java代码就是:

Function<Integer,Integer> plus = (x)->{
    return x+1;
};

Function<Integer,Integer> multip = (x)->{
    return x*3;
};
Integer apply = plus.compose(multip).apply(2); // 此处执行的就是2*3+1=7
// 两个Funtion的调用反过来一下
Integer overApply = multip.compose(plus).apply(2); // 此处执行的就是(2+1)*3=9
第三个方法Function<T, V> andThen(Function<? super R, ? extends V> after)
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
    Objects.requireNonNull(after);
    return (T t) -> after.apply(apply(t));
}

第三个方法一看实现就知道了跟第二个方法是反过来的,直接看代码:

Function<Integer,Integer> plus = (x)->{
    return x+1;
};

Function<Integer,Integer> multip = (x)->{
    return x*3;
};
Integer apply = plus.andThen(multip).apply(2); // 此处执行的就是(2+1)*3=9
// 两个Funtion的调用反过来一下,跟上面的一样
Integer overApply = multip.andThen(plus).apply(2); // 此处执行的就是2*3+1=7

看完之后有木有晕?有木有感觉下面这个andThen有点多余?我感觉有略微有点多余…

第四个方法static <T> Function<T, T> identity()
    /**
     * Returns a function that always returns its input argument.
     *
     * @param <T> the type of the input and output objects to the function
     * @return a function that always returns its input argument
     */
    static <T> Function<T, T> identity() {
        return t -> t;
    }

这个方法返回一个Function,这个Function返回他的参数,类似于y=f(x)的 y=x。写成java代码就是:

Function<Integer, Integer> identity = Function.identity();
Integer apply = identity.apply(5); // apply=5

这个方法看的我有点萌币,不知道哪里用的到,如果有朋友知道这方法在哪里用,怎么用,请告知,谢谢了!


上面的方法整半天都是只能传一个请求参数,然后返回一个值的,万一有多个参数呢?找一下同一个包下面的其他类,发现Function有个大兄deipublic interface BiFunction<T, U, R>
这里写图片描述
这个大兄dei的注释上说了,他有两个参数,一个返回值,然后下面只有2个方法,一个是apply方法,执行Function,另一个是andThen方法,咦,compose方法怎么没了?
先不管了,先来试试他的第一个方法R apply(T t, U u);

BiFunction<Integer,Integer,Integer> plus = (x,y)->{
    return x+y;
};

BiFunction<Integer,Integer,Integer> multip = (x,y)->{
     return x*y;
};

Integer apply = plus.apply(3, 2); // 3+2=5
Integer apply1 = multip.apply(3, 2); // 3*2=6

再看第二个方法

    default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t, U u) -> after.apply(apply(t, u));
    }

返回的是个BiFunction,但是参数是个Function,这样的话,可以这么写:

BiFunction<Integer, Integer, Integer> multip = (x, y) -> {
    return x * y;
};
Function<Integer, Integer> sqr = (x) -> {
    return x * x;
};   
Integer apply = multip.andThen(sqr).apply(3, 5); //(3*5)*(3*5)= 225

他是这么执行的,先执行2个参数的就是上面的multip 方法,然后得到一个结果,再将结果当做参数去执行只有一个参数的sqr方法。所以难怪没有反过来执行的compose方法了,因为不能同时得到2个返回值,所以只能先执行BiFunction方法了。

猜你喜欢

转载自blog.csdn.net/u012843361/article/details/82142482
今日推荐