1. 程式人生 > >Java8之Predicate函式

Java8之Predicate函式

這次我們來分享Predicate這個函式,還是按照以往的風格我們來進行對比的操作,話不多說,我們來切入正題—> 將predicate裡面的函式一一剖析

test()方法

  • 1.我們直接先來看Predicate這個函式的原始碼解釋

    解釋一下

    • 1 . 代表著一個**“斷定式子”**

    • 2 . 這是一個實用的介面—>其中的實用方法指的是test方法

        **PS:下面就是test()方法的程式碼介紹*
      

    test方法的作用是:

    • 1 . 評估引數裡面的表示式(說白了就是驗證傳進來的引數符不符合規則,後面有例子)
    • 2 . 它的返回值是一個boolean型別(這點需要注意一下)。

    下面我們進行操作


import java.util.function.Predicate;

/**
 * 我們來驗證一下,那說的比較矛盾的地方。
 * 1. 評估引數裡面的表示式(說白了就是驗證傳進來的引數符不符合規則,後面有例子)
 *    我們來驗證一下這句話,並且解釋一下。
 */
public class PredicateTestOne {

    public static void main(String[] args) {

        PredicateTestOne predicateTestOne =
new PredicateTestOne(); Predicate<String> predicate = new Predicate<String>() { @Override public boolean test(String s) { return s.equals("zhangsan"); } }; System.out.println(predicate.test("lisi")); System.
out.println("--- --- --- --- --- ---"); System.out.println(predicate.test("zhangsan")); } }

執行結果:

到這裡已經不難理解,為什麼說:評估引數裡面的表示式

  • A.**test()**方法接受一個引數
  • B.判斷這個引數是否符合test()方法體裡面的判斷

在這個程式碼裡面:我們可以看得出來test()方法體裡面判斷的是:傳進來的引數s是否等於zhangsan,而張三這個物件是由外部呼叫傳進來的。

但是這個樣子違反了1.8的新特性—>函數語言程式設計即:我們需要做到的是將函式作為引數,“說白了就是寫更少的程式碼做更多的事”。,我們這個貌似做不到,如果我們要判斷,傳入的引數長度是否大於5或者說判斷傳入的引數是否為奇數或者偶數呢?難道我們還要像以前一樣寫出多個引數麼?當然,不是如果繼續那樣做,Java8的出現將毫無意義!

下面我們來將上面的問題處理一下:(採用傳統的方式和新的方式)

  • 1.判斷傳入的字串的長度是否大於5
  • 2.判斷傳入的引數是否是偶數
  • 3.判斷數字是否大於10

傳統的方法


import java.util.List;
import java.util.function.Predicate;

/**
 * - 1.判斷傳入的字串的長度是否大於5
 * - 2.判斷傳入的引數是否是奇數
 * - 3.判斷數字是否大於10
 */
public class PredicateTestOne {

    public static void main(String[] args) {
        /** 我們先採用傳統的方式 */
        /**  - 1.判斷傳入的字串的長度是否大於5 */
        PredicateTestOne predicateTestOne = new PredicateTestOne();

        System.out.println(predicateTestOne.judgeStringLength("hello"));
        System.out.println(predicateTestOne.judgenumbersOdds(4));
        System.out.println(predicateTestOne.judgeSpecialNumbers(-1));

    }

    /**
     *
     * - 1.判斷傳入的字串的長度是否大於5
     *
     * @param judgeString 待判斷字串
     * @return
     */
    public boolean judgeStringLength(String judgeString) {

        return judgeString.length() > 5 ? true:false;
    }

    /**
     *  - 2.判斷傳入的引數是否是奇數
     *
     * @param number        待判斷的數字
     * @return               1 代表偶數, 0代表奇數
     */
    public int judgenumbersOdds(int number) {

        return number % 2 == 0 ? 1 : 0;
    }

    /**
     * - 3.判斷數字是否大於10
     *
     * @param number        待判斷的數字
     * @return               1. 代表大於10 , 0 代表小於10
     */
    public int judgeSpecialNumbers(int number) {
        return number > 10 ? 1 : 0;
    }
}

Java8中的方法


import java.util.function.Predicate;

/**
 * - 1.判斷傳入的字串的長度是否大於5
 * - 2.判斷傳入的引數是否是偶數
 * - 3.判斷數字是否大於10
 */
public class PredicateTestThree {

    public static void main(String[] args) {

        PredicateTestThree predicate = new PredicateTestThree();

        /** - 1.判斷傳入的字串的長度是否大於5 */
        System.out.println(predicate.judgeConditionByFunction(12345,value -> String.valueOf(value).length() > 5));
        /** - 2.判斷傳入的引數是否是奇數 */
        System.out.println(predicate.judgeConditionByFunction(4,value -> value % 2 == 0));
        /** - 3.判斷數字是否大於10 */
        System.out.println(predicate.judgeConditionByFunction(-1, value-> value > 10));
    }

    public boolean judgeConditionByFunction(int value,Predicate<Integer> predicate) {
        return predicate.test(value);
    }
}

總結一下吧,上面的程式碼主要說了兩件事

    1. 用更少的程式碼幹更多的事
    1. 解釋了test()方法的作用 —> 評估引數裡面的表示式

###Predicate中的其他的方法

  • 1.and()方法,我們先來看下原始碼裡面的解釋

通俗一點解釋: 等同於我們的邏輯與&&,存在短路特性

看下他的程式碼:return:(t) -> test(t) && other.test(t) ,我們的test()方法是返回boolean的,這個是返回一個Predicate,所以我們可以做一個大膽的推斷,and方法是不是要和test()方法去混合使用?下面我們去驗證這個猜測以及去演練這個方法

package com.xsh.java8;

import java.util.function.Predicate;

/**
 * 我們就來看看返回的是什麼
 */
public class PredicateAND {

    public static void main(String[] args) {

        PredicateAND predicateAND = new PredicateAND();

        System.out.println(predicateAND.testAndMethod("zhangsan",
			stringOne -> stringOne.equals("zhangsan"),stringTwo -> stringTwo.length() > 5));
    }

    /**
     *
     * @param stringOne         待判斷的字串
     * @param predicateOne      斷定表示式1
     * @param predicateTwo      斷定表示式2
     * @return                    是否滿足兩個條件
     */
    public boolean testAndMethod(String stringOne, Predicate<String> predicateOne,Predicate<String> predicateTwo) {

        return predicateOne.and(predicateTwo).test(stringOne);
    }
}

上面我們可以知道and方法返回的是Predicate,那麼我們是不是可以無限巢狀下去呢?下面我們來試試


import java.util.function.Predicate;

/**
 * 我們就來看看返回的是什麼
 */
public class PredicateAND {

    public static void main(String[] args) {

        PredicateAND predicateAND = new PredicateAND();

//        System.out.println(predicateAND.testAndMethod("zhangsan",stringOne -> stringOne.equals("zhangsan"),stringTwo -> stringTwo.length() > 5));

        System.out.println(predicateAND.testAndMethod("zhangsan"
                , stringOne -> stringOne.equals("zhangsan")
                ,stringTwo -> stringTwo.length() >5
                ,stringThree -> stringThree.length() % 2 == 0));
    }

    /**
     *
     * @param stringOne         待判斷的字串
     * @param predicateOne      斷定表示式1
     * @param predicateTwo      斷定表示式2
     * @return                    是否滿足兩個條件
     */
    public boolean testAndMethod(String stringOne, Predicate<String> predicateOne, 
	Predicate<String> predicateTwo, Predicate<String> predicateThree) {

        return predicateOne.and(predicateTwo).and(predicateThree).test(stringOne);
    }
}

結論:可行

  • 2 .negate()方法,我們先來看下原始碼裡面的解釋

通俗一點解釋: 等同於我們的邏輯非

ps:返回值一樣需要注意,是Predicate,上面已經驗證過了,可以進行巢狀。

看下他的程式碼:(t) -> !test(t),不用想的太複雜,就是咱們的邏輯非,下面我們去演練這個方法


import java.util.function.Predicate;

public class PredicateNegate {

    public static void main(String[] args) {

        PredicateNegate predicateNegate = new PredicateNegate();

        System.out.println(predicateNegate.testNageteMethod("zhangsan",stringOne -> stringOne.equals("zhangsan")));


    }


    public boolean testNageteMethod(String stringValue, Predicate<String> predicate) {
        return predicate.negate().test(stringValue);
    }
}

  • 3.or()方法,我們先來看下原始碼裡面的解釋

通俗一點解釋: 等同於我們的邏輯或

ps:返回值一樣需要注意,是Predicate,上面已經驗證過了,可以進行巢狀。

看下他的程式碼:(t) -> test(t) || other.test(t) ,不用想的太複雜,就是咱們的邏輯或,就是兩個或多個條件滿足一個就好了,下面我們去演練這個方法


import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;

public class PredicateOr {

    public static void main(String[] args) {

        PredicateOr predicateOr = new PredicateOr();

//        System.out.println(predicateAND.testAndMethod("zhangsan",stringOne -> stringOne.equals("zhangsan"),stringTwo -> stringTwo.length() > 5));

        System.out.println(predicateOr.testOrMethod("zhangsan"
                , stringOne -> stringOne.equals("zhangsan111")
                ,stringTwo -> stringTwo.length() > 50
                ,stringThree -> stringThree.length() % 2 == 0));
    }

    /**
     *
     * @param stringOne         待判斷的字串
     * @param predicateOne      斷定表示式1
     * @param predicateTwo      斷定表示式2
     * @return                    是否滿足兩個條件
     */
    public boolean testOrMethod(String stringOne, Predicate<String> predicateOne, Predicate<String> predicateTwo, Predicate<String> predicateThree) {

//        return predicateOne.and(predicateTwo).test(stringOne);
        return predicateOne.or(predicateTwo).or(predicateThree).test(stringOne);
    }
}

  • 4.isEqual()方法,我們先來看下原始碼裡面的解釋

根據註釋的解釋就是:判斷兩個物件是否相等—> 使用的是Objects裡面的equals()方法進行比較

*Objects解釋如下:

解釋如下: 本類由一些操作物件的靜態工具方法構成,這些工具方法包括了非空檢查、方法的非空引數檢查、
比較物件的hashCode、為物件返回一個字串表示、比較兩個物件,說的很明顯了,比較的兩個物件的HashCode值

通俗一點解釋: 先判斷物件是否為NULL—> 這個由Objects裡面的isNull進行判斷,如果,不為Null的話,那麼接下來用java.lang.object裡面的equals()方法進行比較,下面我們去演練這個方法


import java.util.function.Predicate;

public class PredicateIsEquals {

    public static void main(String[] args) {

        PredicateIsEquals predicate = new PredicateIsEquals();

        String strNull = null;
        System.out.println(predicate.testMethodIsEquals("zhangsan","zhangsan"));
        System.out.println("~~~   ~~~   ~~~   ~~~");
        System.out.println(predicate.testMethodIsEquals("zhangsan","lisi"));
        System.out.println("~~~   ~~~   ~~~   ~~~");
        System.out.println(predicate.testMethodIsEquals(strNull,"zhangsan")); /* 我們來Debug一下這個程式*/

    }


    public boolean testMethodIsEquals(String strValue, String strValue2) {

        return Predicate.isEqual(strValue).test(strValue2);
    }
}

Debug為NULL的情況:

  • 1.第一步

  • 2.第二步

  • 3.猜測與結果

如果目標引數Null的時候,就需要判斷第二個引數是否也為Null,下面我們將第二個引數也換成Null測試一下

import java.util.function.Predicate;

public class PredicateIsEquals {

    public static void main(String[] args) {

        PredicateIsEquals predicate = new PredicateIsEquals();

        String strNull = null;
        String strNull2 = null;
        System.out.println(predicate.testMethodIsEquals("zhangsan","zhangsan"));
        System.out.println("~~~   ~~~   ~~~   ~~~");
        System.out.println(predicate.testMethodIsEquals("zhangsan","lisi"));
        System.out.println("~~~   ~~~   ~~~   ~~~");
        System.out.println(predicate.testMethodIsEquals(strNull,strNull2)); /* 我們來Debug一下這個程式*/

    }


    public boolean testMethodIsEquals(String strValue, String strValue2) {

        return Predicate.isEqual(strValue).test(strValue2);
    }
}

如果,有任何問題,請指正,謝謝。