编程语言
首页 > 编程语言> > 函数式编程初探(与泛型方法的结合)

函数式编程初探(与泛型方法的结合)

作者:互联网

平时在操作集合时,常常有这么一种需求,就是查找符合某一种条件的元素在不在集合中,比如现在有个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());

 

就是讲张三的分数赋值给新返回的李四了

 

函数式风格的代码比较简洁流畅,但是可维护性就见仁见智了,以上

 

标签:Predicate,return,编程,list,collection,test,初探,泛型,action
来源: https://www.cnblogs.com/cloxi/p/15986347.html