Java8学习笔记之行为参数化

用一个例子说明行为参数化带来的变化 - 从苹果仓库中筛选苹果

版本1

从一个苹果集合中选出绿的苹果

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;
    }

版本2

这时,如果需求变了,要从集合中选出红苹果,我们会这样

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;
    }

然后传入颜色参数来筛选

List<Apple> apples = filterApplesByColor(inventory, "red");

版本3

但是,如果现在要选出重量超过150g的苹果呢?在方法参数列表中多加一个weight么?
你会发现我们所有的代码,只有if判断中的条件发生了变化,这违反了DRY原则(Don't Repeat Yourself)。

所以,我们把整个具体行为作为参数来传递,这样,方法体本身的代码就可以复用了。

    // 定义一个接口
    public interface ApplePredicate {
        boolean test(Apple apple);
    }

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

    public class AppleGreenColorPredicate implements ApplePredicate {
        public boolean test(Apple apple) {
            return "green".equals(apple.getColor());
        }
    }
    public static List<Apple> filterApples(List<Apple> inventory, ApplePredicate p) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
            if (p.test(apple)) {
                result.add(apple);
            }
        }
        return result;
    }

现在,我们可以很灵活的调用了

List<Apple> redAndHeavyApples = filterApples(inventory, new AppleHeavyWeightPredicate());

版本4

其实,接口的具体实现,我们只会用到一次。所以,我们可以改成匿名类:

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

现在,代码已经变得非常简洁和灵活了。

版本5

从Java8开始,我们可以利用Lambda表达式,进一步改进代码:

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

现在,调用方法,我们只要一行代码,而且代码的可读性非常好。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,526评论 25 709
  • 第一章 为什么要关心Java 8 使用Stream库来选择最佳低级执行机制可以避免使用Synchronized(同...
    谢随安阅读 1,529评论 0 4
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,253评论 19 139
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,294评论 4 61
  • 自从听了刘同,张嘉佳…那种写东西的冲动就再抑制不住…喜欢简书这个原创平台。仅希望留下些什么记录生活点滴,勾...
    晴箜枫漠阅读 112评论 0 0