Java 8 行为参数化与Lambda

2018-05-14  本文已影响0人  一课一练

我们需要从一堆苹果中按颜色挑出符合要求的苹果。最初,我们可能会按不同的条件写几个相似的方法来做这件事

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

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

好像重复的代码有点太多了,只有颜色的判断条件不同而已,我们做一个重构

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

单单颜色不能满足我们的需求,我们还希望按重量来过滤

public List<Apple> filterApplesBiggerThanWeight(List<Apple> inventory, int weight){
    List<Apple> result = new ArrayList<>();
        for(Apple apple: inventory){
            if(apple.getWeight() > weight ){
                result.add(apple);
            }
        }
    return result;
}

颜色版本和重量版本差的只是判断条件,其他部分依然是相同的,同理对其他属性来说情况也是一样的,所以我们引入行为参数化。

public interface ApplePredicate{
    public boolean test(Apple apple);
}
public List<Apple> filterApples(List<Apple> inventory, ApplePredicate p){
    List<Apple> result = new ArrayList<>();
        for(Apple apple: inventory){
            if(p.test() ){
                result.add(apple);
            }
        }
    return result;
}

public AppleGreenColorPredicate implements ApplePredicate{
    public boolean test(Apple apple){
        return "green".equals(apple.getColor());
    }
}
public AppleWeightPredicate implements ApplePredicate{
    public boolean test(Apple apple){
        return apple.getWeight() > 150; 
    }
}

行为参数化解决了我们的主要问题,但是实现看起来有点啰嗦,我们要实现AppleGreenColorPredicate,AppleWeightPredicate等等,有许多重复的类定义代码。Java 7时代我们使用匿名类来减少一部分代码

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

到了Java 8我们可以使用Lambda来替代不易使用的匿名类

List<Apple> redApples =  filterApples(inventory, apple -> "red".equals(apple.getColor()))

这样就简洁很多了。

上一篇 下一篇

猜你喜欢

热点阅读