lambda表達式:Java.util.function包下Bifunction,Predicate,Supplier,BinaryOperator函數式接口解析

BiFunction

引申 BiFunction 類似於Function 這裏兩個傳入兩個行爲參數
在這裏插入圖片描述
例7BiFunction與Function默認方法的使用

public class FunctionTest2 {

    public static void main(String[] args) {
        FunctionTest2 test = new FunctionTest2();
        System.out.println(test.compose(10, x -> x * 3, y -> y * y)); //300
        System.out.println(test.compose2(10, x -> x * 3, y -> y * y)); //900

        //輸入的行爲的不同 返回的結果不同
        System.out.println(test.compose3(2, 3, (x, y) -> x + y));//5
        System.out.println(test.compose3(2, 3, (x, y) -> x - y));//-1
        System.out.println(test.compose3(2, 3, (x, y) -> x * y));//6
        System.out.println(test.compose3(2, 3, (x, y) -> x / y));//0

        System.out.println(test.compose4(2, 4, (x, y) -> x + y, x -> x * x));//36
    }

    public int compose(int a, Function<Integer, Integer> function1, Function<Integer, Integer> function2) {

        return function1.compose(function2).apply(a);
    }

    public int compose2(int a, Function<Integer, Integer> function1, Function<Integer, Integer> function2) {

        return function1.andThen(function2).apply(a);
    }

    public int compose3(int a, int b, BiFunction<Integer, Integer, Integer> biFunction) {
        //參數怎麼執行是由返回結果根據用戶傳過來的的行爲決定
        return biFunction.apply(a, b);
    }

    public int compose4(int a, int b, BiFunction<Integer, Integer, Integer> biFunction, Function<Integer, Integer> function) {
    	//此時調用apply()相當於當前的函數式接口的參數傳值 行爲就是他的實現
        return biFunction.andThen(function).apply(a, b);
    }
}

例8 BiFunction需求使用
對象

@Data
public class Person {

    private String username;

    private int age;
    }
public class PersonTest {

    public static void main(String[] args) {

        Person person1 = new Person("zhangsan", 20);
        Person person2 = new Person("lisi", 30);
        Person person3 = new Person("wangwu", 40);

        List<Person> list = Arrays.asList(person1, person2, person3);

        PersonTest test = new PersonTest();
//        List<Person> person = test.listPersonByname("zhangsan", list);
//        person.forEach(x -> System.out.println(x));
		/*
			此時行爲是寫死的 只能獲取大於20 的List<Person> 集合
		*/
//        System.out.println(test.listPersonByAge(20, list));

        //不同行爲返回的需求結果不同 具體需求是調用者決定的
        List<Person> listPerson = test.ListPersonByAge2(20, list, (x, y) -> 
        y.stream().filter(person -> person.getAge() > x).collect(Collectors.toList()));
        System.out.println(listPerson);
        System.out.println("=====================================================");
        List<Person> listPerson2 = test.ListPersonByAge2(20, list, (x, y) -> 
        y.stream().filter(person -> person.getAge() <= x).collect(Collectors.toList()));
        System.out.println(listPerson2);

    }

    public List<Person> listPersonByname(String username, List<Person> list) {
        /*
            將List轉換成流 流裏每個對象都是Person對象 判斷爲true的流收集返回
         */
        return list.stream().filter(x -> username.equals(x.getUsername()))
                .collect(Collectors.toList());
    }

    public List<Person> listPersonByAge(Integer age, List<Person> list) {
        //{}寫帶返回結果的語句,需 加上return不然會報錯
        BiFunction<Integer, List<Person>, List<Person>> biFunction = (x, y) ->
                y.stream().filter(person -> person.getAge() > age).collect(Collectors.toList());
        return biFunction.apply(age, list);
    }

    public List<Person> listPersonByAge2(Integer age, List<Person> personList, BiFunction<Integer, List<Person>, List<Person>> biFunction) {
        return biFunction.apply(age, personList);
    }

}

Predicate

在這裏插入圖片描述
在這裏插入圖片描述

public class PredicateTest {

    public static void main(String[] args) {
		/*
			常用做過濾 就是根據行爲動作去返回爲true的值 filter接口行爲參數就是該函數式接口
		*/
        Predicate<String> predicate = x -> x.length() > 5;
        System.out.println(predicate.test("nihaoa")); //true

    }
}

Predicate接口默認方法

	/**
		當前Predicate 行爲test結果 與 傳入行爲 test結果都爲true時爲true 
     */
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    /**
   		返回當前Predicate 行爲test的結果取反
     */
    default Predicate<T> negate() {
        return (t) -> !test(t);
    }

    /**
		 當前Predicate 行爲test結果 與 傳入行爲 test結果有一個爲true時爲true 
     */
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

    /**
   		靜態方法 類似equals 判斷兩個參數是否相等
   		System.out.println(Predicate.isEqual("22").test("22"));//true
     */
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }

例:Predicate默認方法和靜態方法使用

public class PredicateTest2 {

    public static void main(String[] args) {

        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        /**
         * 與傳統相比更加靈活 傳統編程下需要寫5個對應的方法
         */
        PredicateTest2 predicateTest2 = new PredicateTest2();
        predicateTest2.conditionFilter(list, x -> x % 2 == 0);
        System.out.println("=====================");
        predicateTest2.conditionFilter(list, x -> x % 2 != 0);
        System.out.println("=====================");
        predicateTest2.conditionFilter(list, x -> x % x > 2);
        System.out.println("=====================");
        predicateTest2.conditionFilter(list, x -> true); //返回所有的
        System.out.println("=====================");
        predicateTest2.conditionFilter(list, x -> false); //所有的都不返回
        System.out.println("=====================");

        /*
            例:找出集合中大於5並且是偶數的數字
         */
        predicateTest2.conditionFilter2(list, x -> x > 5, x -> x % 2 == 0); //6 8 10


        predicateTest2.conditionFilter3(list, x -> x > 5, x -> x % 2 == 0); // 與上面的相反
        System.out.println("============================");
//        System.out.println(Predicate.isEqual(22).and(x -> (int)x / 22 == 1).test("22"));//false
        System.out.println(Predicate.isEqual(new Date()).test(new Date()));//false

    }


    public void conditionFilter(List<Integer> list, Predicate<Integer> predicate) {

        list.forEach(x -> {
            if (predicate.test(x)) {
                System.out.println(x);
            }
        });
    }

    public void conditionFilter2(List<Integer> list, Predicate<Integer> predicate, Predicate<Integer> integerPredicate) {
        list.forEach(x -> {
            if (predicate.and(integerPredicate).test(x)) {
                System.out.println(x);
            }
        });


    }

    public void conditionFilter3(List<Integer> list, Predicate<Integer> predicate, Predicate<Integer> integerPredicate) {
        list.forEach(x -> {
            if (predicate.and(integerPredicate).negate().test(x)) {
                System.out.println(x);
            }
        });
    }
    
}

Supplier

doc
表示結果的提供者。不要求每次被調用時返回新的或不同的結果。

  • 常用與無參的工廠返回實例 與function相反

在這裏插入圖片描述

public class SupplierTest {

    public static void main(String[] args) {

        Supplier supplier = () -> "nihaoa";
        System.out.println(supplier.get());//nihaoa

    }
}


新增實體類

public class Student {

    private String username = "zhangsan";

    private int age = 20;

    public Student() {
    }

    public Student(String username) {
        this.username = username;
    }

    public String getUsername() {
        return username;
    }

    public int getAge() {
        return age;
    }
}

public class StudentTest {

    public static void main(String[] args) {

        //傳統拿出Student數據需要
        Student student = new Student();
        System.out.println(student.getUsername());

        //lambda表達式
        Supplier<String> supplier = () -> new Student().getUsername();
        System.out.println(supplier.get());
        System.out.println("==================================");
        /*
            構造方法引用  不接收參數返回 Student對象
            new 直接指向對象的無參構造方法
         */
        Supplier<Student> supplier2 = Student::new;
        System.out.println(supplier2.get().getUsername());
    }
}

BinaryOperator

doc文檔
表示對同一類型的兩個參數執行的操作,產生與參數相同類型的結果。對於操作數和結果都是同一類型的情況,這是雙函數的一種特例。
這是一個函數接口 extends BiFunction函數接口,其函數方法是apply(Object,Object)。

在這裏插入圖片描述

**例 BinaryOperator函數接口方法實例 **

public static void main(String[] args) {

        /*
             用來計算相類的的加減乘除運算會變得簡單 我們可以理解爲將方法變成參數
         */
        BinaryOperator<Integer> binaryOperator = (x, y) -> x + y;

        System.out.println(binaryOperator.apply(10, 9));//19
        System.out.println("===");

        BinaryOperatorTest binaryOperatorTest = new BinaryOperatorTest();

        System.out.println(binaryOperatorTest.operation(10, 20, (x, y) -> x + y));
        System.out.println("===");
        System.out.println(binaryOperatorTest.operation(10, 20, (x, y) -> x - y));
        System.out.println("===");
        System.out.println(binaryOperatorTest.operation(10, 20, (x, y) -> x * y));
        System.out.println("===");
        System.out.println(binaryOperatorTest.operation(10, 20, (x, y) -> x / y));
        System.out.println("===");

        /*
            將參數(2, 9)通過comparable 行爲得到的結果 是否大於 0 true 輸出2 否則 輸出 9
         */
        Comparator<Integer> comparator = (x, y) -> x * y;
        System.out.println(BinaryOperator.maxBy(comparator).apply(2, 9));
}



/*
19
===
30
===
-10
===
200
===
0
===
 */

BinaryOperator靜態方法

	 /*
		傳入comparator 行爲 執行compare(a, b)參數得到結果 結果<=0 輸出 參數a 否則 輸出 參數b
		Comparator傳入兩個參數 通過行爲得到的結果 去和0比較 得到 a和b的大小
     */
    public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) {
        Objects.requireNonNull(comparator);
        return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
    }

    /*
    	相反
   		傳入comparator 行爲 執行compare(a, b)參數得到結果 結果>=0 輸出 參數a 否則 輸出 參數b
     */
    public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
        Objects.requireNonNull(comparator);
        return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
    }

例 BinaryOperator函數靜態方法實例

public class BinaryOperatorTest {

    public static void main(String[] args) {
        /*
            自定義
            得到最小的字符?
         */
        //length長度下
        System.out.println(binaryOperatorTest.getShort("hello", "sout", (x, y) -> x.length() - y.length()));//sout
        //首字母排前面的小
        System.out.println(binaryOperatorTest.getShort("hello", "sout", (x, y) -> x.charAt(0) - y.charAt(0)));//hello
    }

    public String getShort(String a, String b, Comparator<String> comparator) {

        return BinaryOperator.minBy(comparator).apply(a, b);
    }
}

Comparator比較器

	傳入兩個值 返回一個int值 常用與兩個參數判斷 正數大 負數小
 int compare(T o1, T o2)

Comparable比較器

	傳入一個值 返回一個int值  正數大 負數小
    public int compareTo(T o);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章