zoukankan      html  css  js  c++  java
  • java8之一文彻底弄懂lambda表达式

    Java 8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁。而且可以更加适应不断变化的需求;

    下面我们循序渐进从案例入手

    一:传统的应对列表筛选的解决方案

    下面给出一个例子:

    public static List<Apple> filterApple(List<Apple> appleList){
            List<Apple> apples = new ArrayList<>();
            for (Apple apple : appleList) {
                if (Objects.equals(apple.getColor(), "green")){
                    apples.add(apple);
                }
            }
            return apples;
        }

    此代码的意思是从一堆苹果中筛选出绿色的苹果。

    假如哪一天,这位农民伯伯不想筛选绿色的苹果,想筛选红色的苹果,那么我们应该怎么做呢?

    最简单的方法就是将上述的代码复制过来,然后改个条件,

    但是后续的需求变动是不确定,那么我们应该怎么面对这种变化的需求?

    此时进阶的做法就是将条件作为参数传入filterApple方法中,例子如下

    public static List<Apple> filterAppleByCondition(List<Apple> appleList,String color){
            List<Apple> apples = new ArrayList<>();
            for (Apple apple : appleList) {
                if (Objects.equals(apple.getColor(), color)){
                    apples.add(apple);
                }
            }
            return apples;
        }

    上述代码很完美的解决了筛选苹果颜色的各种需求,但是现在要对苹果的重量进行筛选呢?是不是懵逼了,那我们改写一下程序

    public static List<Apple> filterApple(List<Apple> appleList,double weight){
            List<Apple> apples = new ArrayList<>();
            for (Apple apple : appleList) {
                if(Double.compare(apple.getWeight(),weight)>0){
                    apples.add(apple);
                }
            }
            return apples;
        }

    这样也完美的解决了筛选苹果的需求,但是,接下来又有需求要一套方法解决筛选苹果的颜色和重量,改写程序如下

    /**
         * flag 为true则筛选颜色,flag为false筛选重量
         * @param appleList
         * @param color
         * @param weight
         * @param flag
         * @return
         */
        public static List<Apple> filterApple(List<Apple> appleList,String color,double weight,boolean flag){
            List<Apple> apples = new ArrayList<>();
            for (Apple apple : appleList) {
                if((!flag&&Double.compare(apple.getWeight(),weight)>0)||(flag&&Objects.equals(apple.getColor(), color))){
                    apples.add(apple);
                }
            }
            return apples;
        }

    上述代码有以下几个缺点:

    1,flag含义不确定

    2,此方法无法应对更加富有变化的需求

    二,行为参数化

    对筛选苹果这一需求进行建模。

    现在我们的需求是对苹果的属性进行筛选,返回值是一个boolean类型,那么我们建立一个接口

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

    此接口的实现即可作为筛选苹果的入参,作为一个行为参数传递给筛选苹果的方法

    public class AppleColorPredicate implements ApplePredicate {
        @Override
        public boolean test(Apple apple) {
            return "green".equals(apple.getColor());
        }
    }
    
    
    
    public class AppleWeightPredicate implements ApplePredicate {
        @Override
        public boolean test(Apple apple) {
            return Double.compare(apple.getWeight(),30)>0;
        }
    }

    经过改造后的筛选苹果方法如下:

     public static List<Apple> filterApple(List<Apple> appleList,ApplePredicate predicate){
            List<Apple> apples = new ArrayList<>();
            for (Apple apple : appleList) {
                if(predicate.test(apple)){
                    apples.add(apple);
                }
            }
            return apples;
        }

    这种做法就是借鉴了策略模式。建立一个统一的上层接口,利用不用的实现作为策略;

    我们现在迈出了行为参数化的第一步,但是很遗憾的是,我们的行为必须通过对象的形式传递给方法

    那么,我们有没有办法直接将代码传递给方法呢?有的,lambda表达式

    List<Apple> red = FilterAppleList.filterApple(appleList, apple -> {
                return Objects.equals(apple.getColor(), "red");
            });
  • 相关阅读:
    XAML语言
    Sqlite 数据库插入标示字段 获取新Id 及利用索引优化查询
    提高C#编程水平的50个要点 ——学生的迷茫
    734条高频词组笔记
    C#读取ini配置文件
    MD5加密
    SQL Server 2000 及 2005 端口修改
    Java控制台程序20例
    Tomcat 6.0+ SQL Server 2005连接池的配
    阿里巴巴离职DBA 35岁总结的职业生涯
  • 原文地址:https://www.cnblogs.com/itqczzz/p/13662779.html
Copyright © 2011-2022 走看看