Java8——初探函数式接口

8 篇文章 0 订阅

这里我们来以筛选苹果举例,如何逐步优化代码,实现函数式编程。
首先,我们的第一个方案可能是下面这样的:

public static List<Apple> filterGreenApples(List<Apple> inventory) { List<Apple> result = new ArrayList<Apple>();
    for(Apple apple: inventory){
      if( "green".equals(apple.getColor() ) { result.add(apple);
    } }
    return result;
}

上面代码对绿色的苹果进行过滤,如果我们想根据其他颜色进行过滤,我们可以将颜色作为参数进行传递,代码如下:

public static List<Apple> filterApplesByColor(List<Apple> inventory, String color) {
    List<Apple> result = new ArrayList<Apple>();
    for (Apple apple: inventory){
if ( apple.getColor().equals(color) ) { result.add(apple);
} }
    return result;
}

以上代码实现了根据苹果的颜色进行筛选,但是当需求更改需要根据苹果重量进行筛选之后怎么办呢?在以前肯定是再写一个方法,通过重量进行筛选,但是这样也就形成了代码重复,显得笨拙。
让我们来看一下更高层次的抽象。一种可能的解决方案是对你的选择标准建模:你考虑的是苹果,需要根据Apple的某些属性来返回一个boolean值。我们把它称为谓词(即返回boolean值的函数),让我们定义一个接口来对选择标准建模,代码如下:
ApplePredicate接口类:

public interface ApplePredicate {
    boolean test(Apple apple);
}

实现该接口之后编写具体的过滤条件,你可以把这些标准看做filter方法的不同行为

    public class AppleHeaveWeightPredicate implements ApplePredicate {
        @Override
        public boolean test(Apple apple) {
            return apple.getWeight() > 150;
        }
    }

    public class AppleGreenColorPredicate implements ApplePredicate {
        @Override
        public boolean test(Apple apple) {
            return "green".equals(apple.getColor());
        }
    }

以上通过通过不同的策略模式来进行筛选,但是这样也存在问题,每个新的筛选条件都需要实现一次接口,显得繁琐,该怎么只利用ApplePredicate来实现不同的实现呢?你需要filterApples方法接受ApplePredicate对象,对Apple做条件测试。这就是行为参数化:让方法接受多种行为作为参数,并在内部使用,来完成不同的行为。
在这里给filterApples方法添加一个参数,让他接受ApplePredicate对象,代码如下:

public static List<Apple> filterApples(List<Apple> inventory, ApplePredicate p ){
        List<Apple> result = new ArrayList<>();
        for(Apple apple : inventory) {
            if(p.test(apple)) //谓词对象封装了测试苹果的条件
                System.out.println(apple.toString());
                result.add(apple);
        }
        return result;
    }

在这里一种方式是通过匿名类实现ApplePredicate对象,重写筛选的例子实现过滤:

List<Apple> redApples = filterApples(inventory, new ApplePredicate() { public boolean test(Apple apple){
    return "red".equals(apple.getColor());
}
 });

但是我们可以通过更简单的方式实现筛选,通过filterApples(inventory, (apple -> apple.getWeight() < 150))使用。
如此便实现了一个参数多种行为,我们可以通过传递不同的行为打到不同的目的。
这里写图片描述

对于上面的函数还可以更进一步抽象化,引入泛型,将list的参数抽象化

public static <T> List<T> filter(List<T> list, Predicate<T> p) {//这里使用了Java8提供的Predicate方法
        List<T> result = new ArrayList<T>();
        for(T e : list) {
            if(p.test(e)) {
                result.add(e);
            }
        }
        return result;
    }

以上便是使用函数式接口的一个简单例子。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值