一、函数式编程

函数编程演化历程

  1. 将业务代码直接写死代码里
  2. 将单一维度的条件作为参数传入方法中,方法内根据参数进行业务逻辑实现。
  3. 将多个维度的条件作为参数传入方法中,业务实现需要根据不同的参数处理不同的逻辑。
  4. 将业务逻辑封装为一个实体类,方法接受实体类为参数,方法内部调用实体类的处理逻辑。
  5. 调用方法时不再创建实体类,而是使用匿名函数的形式替代。
  6. 使用Lambda表达式替代匿名函数的形式,作为方法的参数,真正实现判断逻辑参数化传递。

案例

目的:针对不同需求对购物车的的商品进行过滤筛选

准备

  1. 商品对象
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Goods {
        // 编号
        private Integer goodId;
        // 商品名称
        private String goodName;
        // 商品类型
        private Enum goodType;
        // 单价
        private Double goodPrice;
        // 总价
        private Double goodTotalPrice;
        // 数量
        private Integer totalNum;
    }
    
  2. 商品枚举类
/**
 * 商品类型的枚举类
 */
public enum GoodTypeEnum {
    APPAREL(10,"服装类"),
    DIGITAL(20,"数码类"),
    BOOKS(30,"图书类"),
    SPORTS(40,"运动类");
    // 商品类型的编号
    private Integer code;
    // 商品类型的名称
    private String name;

    /**
     * 构造函数
     * @param code
     * @param name
     */
    GoodTypeEnum(Integer code, String name) {
        this.code = code;
        this.name = name;
    }
}    
  1. 模拟商品数据
    /**
     * 模拟商品数据
     */
    private static List<Goods> goodsList= new ArrayList<Goods>(){
        {
            add(new Goods(111,"无人机", GoodTypeEnum.DIGITAL,10000.00, 10000.00,1));
            add(new Goods(112,"VR一体机", GoodTypeEnum.DIGITAL,13000.00, 13000.00,1));
            add(new Goods(113,"衬衫", GoodTypeEnum.APPAREL,100.00, 300.00,3));
            add(new Goods(114,"牛仔裤", GoodTypeEnum.APPAREL,120.00, 120.00,1));
            add(new Goods(115,"Java编程思想", GoodTypeEnum.BOOKS,80.00, 80.00,1));
            add(new Goods(116,"Java核心技术", GoodTypeEnum.BOOKS,90.00, 90.00,1));
            add(new Goods(117,"算法", GoodTypeEnum.BOOKS,60.00, 60.00,1));
            add(new Goods(118,"跑步机", GoodTypeEnum.SPORTS,3600.00, 3600.00,1));
    
        }
    };
    
    /**
     * 获取商品列表
     * @return
     */
    public  List<Goods> getGoodsList(){
        return goodsList;
    }
    

实现

Version 1.0.0

    /**
     * Version 1.0.0
     * 找出购物车中所有数码类产品
     * @param goodsList
     * @return
     */
    public  List<Goods> filterGoodsList(List<Goods> goodsList){
        List<Goods> result = new ArrayList<>();
        for (Goods goods : goodsList) {
            if (GoodTypeEnum.DIGITAL.equals(goods.getGoodType())){
                result.add(goods);
            }
        }
        return result;
    }

测试

    @Test
    public void version1(){
        GoodsService goodsService = new GoodsService();
        List<Goods> goodsList = goodsService.getGoodsList();
        List<Goods> goods = goodsService.filterGoodsList(goodsList);
        System.out.println(JSON.toJSONString(goods,true));

    }

Version 2.0.0

    /**
     * 根据类型找出购物车中对应类型的产品
     * @param goodsList
     * @return
     */
    public  List<Goods> filterGoodsList(List<Goods> goodsList,GoodTypeEnum goodType){
        List<Goods> result = new ArrayList<>();
        for (Goods goods : goodsList) {
            if (goodType.equals(goods.getGoodType())){
                result.add(goods);
            }
        }
        return result;
    }

测试

    @Test
    public void version2(){
        GoodsService goodsService = new GoodsService();
        List<Goods> goodsList = goodsService.getGoodsList();
        List<Goods> goods = goodsService.filterGoodsList(goodsList, GoodTypeEnum.SPORTS);
        System.out.println(JSON.toJSONString(goods,true));

    }

Version 3.0.0

    /**
     * 支持通过商品类型或者总价来过滤商品
     * @param goodsList
     * @param goodType
     * @param totalPrice
     * @param goodTypeOrPrice - true:根据商品类型 false:根据商品总价
     * @return
     */
    public  List<Goods> filterGoodsList(List<Goods> goodsList,GoodTypeEnum goodType,Double totalPrice,boolean goodTypeOrPrice){
        List<Goods> result = new ArrayList<>();
        for (Goods goods : goodsList) {
            //goodTypeOrPrice - true:根据商品类型 false:根据商品总价
            if (goodTypeOrPrice && goodType.equals(goods.getGoodType())||
                    !goodTypeOrPrice && goods.getGoodTotalPrice()>totalPrice
            ){
                result.add(goods);
            }
        }
        return result;
    }

测试

    @Test
    public void version3(){
        GoodsService goodsService = new GoodsService();
        List<Goods> goodsList = goodsService.getGoodsList();
        List<Goods> goods = goodsService.filterGoodsList(goodsList, GoodTypeEnum.SPORTS,1000.00,false);
        System.out.println(JSON.toJSONString(goods,true));

    }

Version 4.0.0

    /**
     * 根据不同的goods判断标准,对商品列表进行过滤
     * @param goodsList
     * @param goodsPredicate(或者Predicate接口) - 不同的商品判断标准
     * @return
     */
    public  List<Goods> filterGoodsList(List<Goods> goodsList,GoodsPredicate goodsPredicate){
        List<Goods> result = new ArrayList<>();
        for (Goods goods : goodsList) {
            if (goodsPredicate.test(goods)){
                result.add(goods);
            }
        }
        return result;
    }
    /**
     * Goods判断标准策略接口
     */
    public interface GoodsPredicate {
        /**
         * 选择判断标准
         * @param goods
         * @return
         */
        boolean test(Goods goods);
    }
    /**
     * Goods商品类型为图书类型的判断标准
     */
    public class  BooksGoodsPredicate implements GoodsPredicate {
    
        @Override
        public boolean test(Goods goods) {
            return GoodTypeEnum.BOOKS.equals(goods.getGoodType());
        }
    }

测试

    @Test
    public void version4(){
        GoodsService goodsService = new GoodsService();
        List<Goods> goodsList = goodsService.getGoodsList();
        List<Goods> goods = goodsService.filterGoodsList(goodsList,new BooksGoodsPredicate());
        System.out.println(JSON.toJSONString(goods,true));

    }

Version 5.0.0

考虑到判断标准多样化,没必要为标准写一个类,可以使用匿名内部类根据情况直接判断

    @Test
    public void version5(){
        GoodsService goodsService = new GoodsService();
        List<Goods> goodsList = goodsService.getGoodsList();
        List<Goods> goods = goodsService.filterGoodsList(goodsList,new GoodsPredicate(){
            @Override
            public boolean test(Goods goods){
                return goods.getGoodTotalPrice()>5000;
            }
        });
        System.out.println(JSON.toJSONString(goods,true));

    }

Version 6.0.0

还可以进一步优化,使用lambda表达式

    @Test
    public void version6(){
        GoodsService goodsService = new GoodsService();
        List<Goods> goodsList = goodsService.getGoodsList();
        List<Goods> goods = goodsService.filterGoodsList(goodsList,(Goods good) -> good.getGoodTotalPrice()>10000);
        System.out.println(JSON.toJSONString(goods,true));

    }
原文地址:https://www.cnblogs.com/bigfairy/p/14002040.html