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已經幫我們提供了!