java8新特性之lamda表示式應用java策略模式
java8的lamda表示式提供了有四種最常用的函式式介面型別:簡單理解函式式介面:就是介面中只有一個抽象方法的介面
1:消費型介面:Consumer 有入參 無返回介面
2:供給型介面:Supplier 無入參 有返回結果
3:function介面:有入參 有返回結果
4:斷言型介面Predicator: 判斷返回結果是否true
現在模擬一個小小的需求:
一個集合:
List<UserInfo> userList = Arrays.asList( new UserInfo(1,"張三",29), new UserInfo(1,"李四",21), new UserInfo(1,"王五",11), new UserInfo(1,"趙六",8) )
需求1:我們要取出年齡小於20週歲的員工
需求2:我們要取出名字含有(李)字的員工
方法一:
new一個集合,然後for迴圈,if(年齡小於20)則新增到new的集合中。
再new一個集合,然後for迴圈,if(名字含有李字)則新增到new的集合中。
這是沒有任何策略的流水似實現。最容易理解。效率最低。如果有新的需求。就要sbb的擂程式碼。
方法二:採用策略設計模式
1:設計一個Filter介面。接口裡面提供一個方法。方法名稱就叫filterByAge() ,返回一個boolean型別。
/** * : 方法描述資訊 * * @author liyy * @date 2018-09-09 13:59 */ public interface FilterPredicator<T> { public boolean filter(T t); }
2: 寫一個實現類實現這個Filter介面,重寫裡面的方法。如果滿足某個過濾條件返回true
package com.springmvc.filter; import com.springmvc.pojo.UserInfo; /** * : 描述資訊 * * @author liyy * @date 2018-09-09 14:01 */ public class MyFilterPredicator implements FilterPredicator<UserInfo>{ @Override public boolean filter(UserInfo userInfo) { return userInfo.getAge()>20; } }
3:對集合採用實現中的策略進行過濾。就可以拿到最後需要的資料
public List<UserInfo> getListByAge(List<UserInfo> list,Filter<UserInfo> filter){
List<UserInfo> filterList = new ArrayList();
for(UserInfo u:list){
if(filter.filter(u)){
filterList.add(u);
}
}
}
4:直接呼叫getListByAge方法傳入兩個引數即可。此時如果新加一個需求按名字進行過濾。那麼這裡不需要新增任何程式碼。只
需要在介面實現類中。新增一個實現類即可。
List<UserInfo> users = getListByAge(list,new MyFilter());
以上就是根據實際的需求採用不同的策略進行篩選獲取最終的結果。
那麼還是覺得有點麻煩。我每新增一個需求就要新增一個實現類。這也蠻多的。可以接著優化我們的程式碼
那就是把我們的實現類變成匿名內部類。匿名內部類的作用一個兩個:1:簡化程式碼2:讀複雜的業務邏輯提供內部支援。例如
我們常用的Comparator介面、Runnable介面
1: Comparator<UserInfo> comparator = new Comparator<UserInfo>() {
@Override
public int compare(UserInfo o1, UserInfo o2) {
return 0;
}
};
MyThread整合Thread抽象類
2: Thread t = new Runnable(new MyThread()){
@Override
public void run(){
}
}
改造我們現有的程式碼:
List<UserInfo> users = getListByAge(list,new MyFilter());程式碼改造成
List<UserInfo> users = getListByAge(userInfoList, new Filter<UserInfo>() {
@Override
public boolean filter(UserInfo userInfo) {
return userInfo.getAge()>20;
}
});
用匿名內部類就可以替換掉原有實現類。直接在filter方法裡面寫具體的策略。在java1.8之前這已經是最優程式碼沒法再優化了
但是java1.8提供了更強大的流式處理。簡單幾行搞定上述需求
List<UserInfo> resultList = list.stream().filter(u -> u.getAge>20).collect(Collectors.toList());
一句就搞定了
加入我要輸出使用者的姓名呢?
List<String> nameList = list.stream().map(UserInfo::getName()).collect(Collectors.toList());
就是這麼的NB.不服不行!
最後:java提供的最後一個函式是介面Predicator可以代替我們上面自定義的介面。java已經幫我們提供了!