美文网首页Java学习笔记
Java8学习笔记之行为参数化

Java8学习笔记之行为参数化

作者: Joepis | 来源:发表于2017-04-19 12:46 被阅读68次

    摘要: 原创出处 http://peijie2016.gitee.io 欢迎转载,保留摘要,谢谢!

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

    版本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()));
    

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

    相关文章

      网友评论

        本文标题:Java8学习笔记之行为参数化

        本文链接:https://www.haomeiwen.com/subject/npbczttx.html