Java8-3-深刻理解函數式編程模型

上一篇文章中,咱們整體介紹了建立函數式接口實例的幾種方式以及Java8中接口新增的默認方法特性,接下來咱們來看下Java8中已經爲咱們提供的幾種典型的函數式接口
先看一個示例編程

public class FunctionTest {
    public static void main(String[] args) {
        FunctionTest functionTest = new FunctionTest();
        int i2 = functionTest.add2(2);
        int i3 = functionTest.add3(2);
        int i4 = functionTest.add4(2);
    }

    //邏輯提早定義好
    public int add2(int i){
        return i + 2;
    }

    //邏輯提早定義好
    public int add3(int i){
        return i + 3;
    }

    //邏輯提早定義好
    public int add4(int i){
        return i + 4;
    }
}

FunctionTest中定義了三個方法,分別把參數加2,加3,加4而後分別把結果返回,那若是之後還要取到參數的平方或者各類其餘的運算,就還須要定義更多的處理方法。接下來看下若是使用Java8提供的Function接口會有哪些改進
首先看下Function接口定義segmentfault

@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);
    .
    .省略
    .
}

該函數式接口惟一的抽象方法apply接收一個參數,有返回值。看下使用方式api

public class FunctionTest {
    public static void main(String[] args) {
        FunctionTest functionTest = new FunctionTest();

        int result2 = functionTest.compute(5, num -> num + 2);
        int result3 = functionTest.compute(5, num -> num + 2);
        int result4 = functionTest.compute(5, num -> num + 2);
        int results = functionTest.compute(5, num -> num * num);

    }

    //調用時傳入邏輯
    public int compute(int i, Function<Integer,Integer> function){
        Integer result = function.apply(i);
        return result;
    }
}

咱們在FunctionTest中定義了compute方法,方法的第一個參數是要運算的數據,第二個參數是函數式接口Function的實例,當執行compute方法時,會將第一個參數交給第二個參數Function中的apply方法處理,而後返回結果。
這樣咱們能夠將方法定義的更抽象,代碼重用性也就越高,每次將要計算的數據和計算邏輯一塊兒做爲參數傳遞給compute方法就能夠。是否是有點體驗到函數式編程的靈活之處。
注:由於表達式只有一行語句 num -> num + 2 能夠省略了return 關鍵字 若是爲了更加直觀能夠寫成 num -> return num + 2app

Supplier接口,默認抽象方法get不接收參數,有返回值函數式編程

@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

相似工廠模式函數

public class SupplierTest {
    public static void main(String[] args) {
        Supplier<String> supplier = String::new;
        String s = supplier.get();
    }
}

這裏使用構造方法引用的方式建立Supplier實例,經過get直接返回String對象this

Predicate接口lua

@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);
    .
    .省略
    .
}

接收一個參數,返回布爾類型,使用方式code

public class PredicateTest {
    public static void main(String[] args) {
        Predicate<String> predicate = s -> s.length() > 5;
        System.out.println(predicate.test("hello"));
    }
}

定義了一個接收一個參數返回布爾值的lambda表達式,賦值給predicate,就能夠直接對傳入參數進行校驗對象

再看一個Predicate例子

public class PredicateTest {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        PredicateTest predicateTest = new PredicateTest();
        List<Integer> result = predicateTest.conditionFilter(list, integer -> integer > 5);
        result.forEach(System.out::println);
    }

    public List<Integer> conditionFilter(List<Integer> list, Predicate<Integer> predicate){
        return list.stream().filter(predicate).collect(Collectors.toList());
    }
}

這段程序的邏輯是找到集合裏大於5的數據,打印到控制檯。咱們具體分析一下conditionFilter方法,第一個參數是待遍歷的集合,第二個參數是Predicate類型的實例,還記得Predicate接口中的抽象方法定義嗎,接收一個參數返回布爾類型。list.stream()是建立了一個針對此集合的Stream對象(先簡單認識一下),而後調用Stream的filter方法對結果進行過濾,過濾的條件就是Predicate接口的實現,最後collect(Collectors.toList());是將過濾後的結果收集起來放置到一個新的集合中並返回。
其中涉及到Srteam api的知識點咱們會在後續章節中詳細介紹,如今只關心Predicate的使用就能夠。

接下來調用conditionFilter方法

List<Integer> result = predicateTest.conditionFilter(list, integer -> integer > 5);

list是待遍歷的集合
integer -> integer > 5 lambda表達式是對Predicate接口的具體實現

result.forEach(System.out::println);

最後,方法引用實例化一個Consumer對象,把結果輸出到控制檯。

能夠看出,lambda表達式和stream api結合起來使用讓代碼更簡潔更加語義化,即便以前沒接觸過stream api也能大概看出conditionFilter方法的功能。

小結:本篇繼續介紹Java8函數式編程模型,介紹了幾個內置的函數式接口使用方式,並在最後一個示例引出stream api知識點,後續會對stream api進行詳細的介紹,若是以爲本篇文章對你有所幫助幫忙贊一下。

下一篇

相關文章
相關標籤/搜索