[六] 函數式接口的復合方法示例 predicate 謂詞邏輯運算 Function接口 組合運算 比較器 逆序 比較鏈


復合的方法

有些函數式接口提供了允許復合的方法

也就是可以將Lambda表達式復合成為一個更加復雜的方法

之前的章節中有說到:

接口中的compose, andThen, and, or, negate 用來組合函數接口而得到更強大的函數接口

另外還有比較器中的reversed thenComparing可以用於組合運算

這幾個方法分別位於Function以及Predicate中

image_5b7bd742_6b17

image_5b7bd742_7644

image_5b7bd742_59d3

方法示例

組合方法 andThen compose

分別計算輸入初始值1,2 在四個不同的函數里面的結果

Function<Integer, Integer> f = x -> x + 2;

Function<Integer, Integer> g = x -> x * 4;

Function<Integer, Integer> fAndThenG = f.andThen(g);

for(int i = 1;i<3;i++){
System.out.println(fAndThenG.apply(i));
}

System.out.println("--------------");

Function<Integer, Integer> gAndThenF = g.andThen(f);

for(int i = 1;i<3;i++){
System.out.println(gAndThenF.apply(i));

}

System.out.println("--------------");

Function<Integer, Integer> fComposeG = f.compose(g);
for(int i = 1;i<3;i++){ System.out.println(fComposeG.apply(i)); } System.out.println("--------------"); Function<Integer, Integer> gComposeF = g.compose(f);
for(int i = 1;i<3;i++){ System.out.println(gComposeF.apply(i)); }

初始值為1,2

f (x)= x -> x + 2;

g(x) = x -> x * 4;

復合后:

f(g(x)) = (x * 4)+2

g(f(x)) = (x+2)*4

結果分別是

6,10

12,16

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

再看一下打印結果信息

image_5b7bd742_3951

andThen表示 接着進行下一步運算,也就是結果進入到下一個函數中

調用者第一個函數的結果作為被調用者第二個函數的參數

也就是

第二個函數(第一個函數結果)    g(f(x)) 的形式

 

compose 表示組合組成的含義 表示 由誰組成  也就是調用者函數由被調用者函數組成

也就是

第一個函數(第二個函數 結果)  f(g(x)) 的形式

顯然 對於固定的兩個函數  f  g  

調用與被調用的順序  和 方法的選擇這兩者 

只能組合出來兩種  f(g(x))  或者  g(f(x))

注意,此處為了更便於表達使用了數學函數的樣式展現,但是 Function意味着 輸入轉換為輸出  不要有思維局限性認為就是為了處理數學問題


and, or, negate 與 或  非

與或非 和我們平時理解的概念並無二致 就是執行邏輯運算
and和or方法是按照在表達式鏈中的位置,從左向右確定優先級的。因此,a.or(b).and(c)可以看作(a || b) && c

class Stu{

private String name;
private String sex;
private Integer age;

public Stu(){


}

public Stu(String name,String sex,Integer age){
this.name = name;
this.sex = sex;
this.age = age;

}


//此處省略了 getter setter方法



@Override

public String toString() {
final StringBuilder sb = new StringBuilder("Stu{");
sb.append("name='").append(name).append('\'');
sb.append(", sex='").append(sex).append('\'');
sb.append(", age=").append(age);
sb.append('}');

return sb.toString();

}

}

 

主函數中的測試代碼(省略主函數與測試類)

List<Stu> stuList = new ArrayList(){
{
add(new Stu("Stu1","男",15));
add(new Stu("Stu2","女",18));
add(new Stu("Stu3","男",13));
add(new Stu("Stu4","男",28));
add(new Stu("Stu5","女",58));
add(new Stu("Stu6","女",18));
add(new Stu("Stu7","女",30));
add(new Stu("Stu8","男",6));
}
};

System.out.println(
stuList.stream().filter(i->i.getSex().equals("男")).filter(i->i.getAge().compareTo(18)>0).collect(Collectors.toList())
);

Predicate<Stu> checkSex = i->i.getSex().equals("男");
Predicate<Stu> checkAge = i->i.getAge().compareTo(18)>0;

System.out.println(
stuList.stream().filter(checkSex.and(checkAge)).collect(Collectors.toList())
);

System.out.println(
 stuList.stream().filter(checkSex.negate()).collect(Collectors.toList())
);

 

image_5b7bd742_700a

使用邏輯運算,描述更加清晰,更好理解,更符合聲明式編程的思想
可以將多個不同的條件進行組合,靈活性更高


比較器方法

Stream中有 sorted方法

image_5b7bd742_3131

方法的參數正是一個Comparator,提供了

逆序 reversed

和 

比較器鏈thenComparing   (還有基本類型特化方法)

List<Stu> stuList = new ArrayList(){
{
add(new Stu("Stu1","男",15));
add(new Stu("Stu2","女",18));
add(new Stu("Stu3","男",13));
add(new Stu("Stu4","男",28));
add(new Stu("Stu5","女",58));
}
};

Comparator<Stu> cName = Comparator.comparing(Stu::getName);
Comparator<Stu> cSex = Comparator.comparing(Stu::getSex);
Comparator<Stu> cAge = Comparator.comparing(Stu::getAge);

System.out.println(
stuList.stream().sorted(cName).collect(Collectors.toList())
);

System.out.println(
stuList.stream().sorted(cName.reversed()).collect(Collectors.toList())
);

System.out.println(
stuList.stream().sorted(cSex).collect(Collectors.toList())
);


System.out.println(
stuList.stream().sorted(cSex.thenComparing(cAge)).collect(Collectors.toList())
);

 

 

 

從結果可以看得出來 

第一組按照姓名升序

第二組按照姓名降序

第三組按照性別排序,但是年齡沒有排序

第四組按照性別排序,同性別的按照年齡排序


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM