1. 程式人生 > >java8新特性之lamda表示式應用java策略模式

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