有些函數式接口提供了容許複合的方法編程
也就是能夠將Lambda表達式複合成爲一個更加複雜的方法數組
以前的章節中有說到:app
接口中的compose, andThen, and, or, negate 用來組合函數接口而獲得更強大的函數接口ide
另外還有比較器中的reversed thenComparing能夠用於組合運算函數
這幾個方法分別位於Function以及Predicate中測試
方法示例ui
分別計算輸入初始值1,2 在四個不一樣的函數裏面的結果this
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,2spa f (x)= x -> x + 2;3d g(x) = x -> x * 4; |
複合後: f(g(x)) = (x * 4)+2 g(f(x)) = (x+2)*4 |
結果分別是 6,10 12,16
|
再看一下打印結果信息
andThen表示 接着進行下一步運算,也就是結果進入到下一個函數中
調用者第一個函數的結果做爲被調用者第二個函數的參數
也就是
第二個函數(第一個函數結果) g(f(x)) 的形式
compose 表示組合組成的含義 表示 由誰組成 也就是調用者函數由被調用者函數組成
也就是
第一個函數(第二個函數 結果) f(g(x)) 的形式
顯然 對於固定的兩個函數 f g
調用與被調用的順序 和 方法的選擇這二者
只能組合出來兩種 f(g(x)) 或者 g(f(x))
注意,此處爲了更便於表達使用了數學函數的樣式展示,可是 Function意味着 輸入轉換爲輸出 不要有思惟侷限性認爲就是爲了處理數學問題
與或非 和咱們平時理解的概念並沒有二致 就是執行邏輯運算
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()) );
使用邏輯運算,描述更加清晰,更好理解,更符合聲明式編程的思想
能夠將多個不一樣的條件進行組合,靈活性更高
Stream中有 sorted方法
方法的參數正是一個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()) );
從結果能夠看得出來
第一組按照姓名升序
第二組按照姓名降序
第三組按照性別排序,可是年齡沒有排序
第四組按照性別排序,同性別的按照年齡排序