1. 程式人生 > 其它 >函數語言程式設計初探(與泛型方法的結合)

函數語言程式設計初探(與泛型方法的結合)

平時在操作集合時,常常有這麼一種需求,就是查詢符合某一種條件的元素在不在集合中,比如現在有個List<User>,我們想知道這個集合裡有沒有名字叫張三的人,有的話會做123,沒有的話會做456之類的。

一般我們會寫以下程式碼

     List<User> collect = list.stream().filter(p -> "張三".equals(p.getName())).collect(Collectors.toList());
     if (CollectionUtils.isNotEmpty(collect)){ //do something
}else { //do something }

 

如果在一個方法裡,需要頻繁這麼操作,那未免顯得有些繁瑣,所以可以把這個判斷操作抽出來作為一個函式呼叫,既然是集合,那就需要支援泛型,所以有了以下方法

private <T> boolean findInList(Collection<? extends T> collection, Predicate<? super T> test){
        for (T t : collection) {
            if (test.test(t)){
                
return true; } } return false; }

 

針對一個集合,給定一個Predicate,遍歷這個集合,如果有一個元素滿足Predicate的要求,那就返回true,否則返回false,所以上面的判斷方法可以簡化成

     if (findInList(list,b -> "張三".equals(b.getName()))){
            //do something
        }else {
            //do something
        }

 

更進一步,我們可以把註釋的do something也抽象成一個函式式方法,如果我們需要在找到特定元素之後對這個元素做什麼,那可以在後面加一個Consumer

private <T> void ifInListDo(Collection<? extends T> collection,Predicate<? super T> test, Consumer<? super T> action){
        for (T t : collection) {
            if (test.test(t)){
                action.accept(t);
            }
        }
    }

比如我們想在找到名字叫張三的人之後輸出他的分數,那麼就可以有以下程式碼

ifInListDo(list,a -> "張三".equals(a.getName()),(a)->{System.out.println("張三的分數 : " + a.getScore());});

 

或者我們需要找到這個元素之後返回另一個元素,那可以把Consumer換成Supplier,如下

private <T> T ifInListGet(Collection<? extends T> collection,Predicate<? super T> test, Supplier<? extends T> action){
        for (T t : collection) {
            if (test.test(t)){
                return action.get();
            }
        }
        return null;
    }

 

就可以像這樣呼叫

User b = ifInListGet(list,a -> "張三".equals(a.getName()),()-> User.builder().Name("李四").build());

這個意思是如果list裡有張三,那就得到了一個叫李四的User物件

 

最後,如果我們找到張三後,想根據張三的某些屬性返回一個新物件,那可以將Supplier換成原始的Function

private <T> T ifInListGet(Collection<? extends T> collection,Predicate<? super T> test, Function<? super T, ? extends T> action){
        for (T t : collection) {
            if (test.test(t)){
                return action.apply(t);
            }
        }
        return null;
    }

 

呼叫如下

User b = ifInListGet(list,a -> "張三".equals(a.getName()),(b)-> User.builder().Name("李四").Score(b.getScore()).build());

 

就是講張三的分數賦值給新返回的李四了

 

函式式風格的程式碼比較簡潔流暢,但是可維護性就見仁見智了,以上