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方法了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章