Java高效编程

函数式编程

需求

有一些商品信息,现在需要将这些商品添加到购物车中获取购物车中的商品信息,然后完成以下需求.

  1. 找出购物车中所有属于电子数码 的商品
  2. 根据商品类型查找商品
  3. 通过商品类型或总价过滤商品
  4. 根据不同的商品判断标准查找商品

商品实体类

java 复制代码
package lambda.cart;

/**
 * 下单商品信息对象
 */
public class Sku {
    // 商品编号
    private Integer skuId;
    // 商品名称
    private String skuName;
    // 商品单价
    private Double skuPrice;
    // 商品个数
    private Integer totalNum;
    // 商品总价
    private Double totalPrice;
    // 商品分类
    private Enum skuCategory;


    /**
     * 有参构造
     * @param skuId
     * @param skuName
     * @param skuPrice
     * @param totalNum
     * @param totalPrice
     * @param skuCategory
     */
    public Sku(Integer skuId, String skuName, Double skuPrice, Integer totalNum, Double totalPrice, Enum skuCategory) {
        this.skuId = skuId;
        this.skuName = skuName;
        this.skuPrice = skuPrice;
        this.totalNum = totalNum;
        this.totalPrice = totalPrice;
        this.skuCategory = skuCategory;
    }

    public Integer getSkuId() {
        return skuId;
    }

    public String getSkuName() {
        return skuName;
    }

    public Double getSkuPrice() {
        return skuPrice;
    }

    public Integer getTotalNum() {
        return totalNum;
    }

    public Double getTotalPrice() {
        return totalPrice;
    }

    public Enum getSkuCategory() {
        return skuCategory;
    }
}

商品分类枚举

java 复制代码
package lambda.cart;

/**
 * 商品分类枚举
 */
public enum SkuCategoryEnum {
    CLOTHING(10, "服装"),
    DIGITAL(20, "数码产品"),
    SPORTS(30, "运动类"),
    BOOKS(40, "书籍类");

    // 商品类型的编号
    private Integer code;
    // 商品类型的名称
    private String name;

    /**
     * 构造方法
     *
     * @param code
     * @param name
     */
    SkuCategoryEnum(Integer code, String name) {
        this.code = code;
        this.name = name;
    }


}

添加所有商品信息到购物车中

java 复制代码
private static List<Sku> cartSkuList = new ArrayList<Sku>() {
        {
            add(new Sku(654032, "无人机", 22.2, 2, 44.4, SkuCategoryEnum.DIGITAL));
            add(new Sku(654033, "VR眼镜", 11.1, 2, 22.2, SkuCategoryEnum.DIGITAL));
            add(new Sku(654034, "充气娃娃", 1000.0, 2, 2000.0, SkuCategoryEnum.SPORTS));
            add(new Sku(654035, "Java核心技术", 50.0, 2, 100.0, SkuCategoryEnum.BOOKS));
            add(new Sku(654036, "Python编程", 49.0, 2, 96.0, SkuCategoryEnum.BOOKS));
            add(new Sku(654037, "女装", 66.0, 1, 66.0, SkuCategoryEnum.CLOTHING));
        }
    };

获取购物车中的所有商品

java 复制代码
public static List<Sku> getCartSkuList() {
        return cartSkuList;
    }

需求分析和完成

找出购物车中所有属于电子数码的商品

  • 实现方式:使用循环遍历购物车中的所有商品信息,然后使用枚举进行比对
java 复制代码
public static List<Sku> filterElectronicsSku(List<Sku> cartSkuList) {
        List<Sku> result = new ArrayList<>();
        for (Sku sku : cartSkuList
        ) {
            if (SkuCategoryEnum.DIGITAL.equals(sku.getSkuCategory())) {
                result.add(sku);
            }
        }
        return result;
    }

根据商品类型查找商品

  • 实现方式:将商品类别枚举作为参数传递给方法,使用商品分类枚举进行比对
java 复制代码
/**
     * 根据商品类型查找商品
     * Version:2.0(单一维度条件参数化)
     *
     * @param cartSkuList
     * @param skuCategoryEnum
     * @return
     */
    public static List<Sku> filterSkuByCategory(List<Sku> cartSkuList, SkuCategoryEnum skuCategoryEnum) {
        List<Sku> result = new ArrayList<>();
        for (Sku sku : cartSkuList
        ) {
            if (skuCategoryEnum.equals(sku.getSkuCategory())) {
                result.add(sku);
            }
        }
        return result;
    }

通过商品类型或总价过滤商品

java 复制代码
/**
     * 通过商品类型或总价过滤商品
     * Version: 3.0
     *
     * @param cartSkuList
     * @param categoryEnum
     * @param totalPrice
     * @param categoryOrPrice false:使用价格过滤,true使用分类
     * @return
     */
    public static List<Sku> filterSku(
            List<Sku> cartSkuList,
            SkuCategoryEnum categoryEnum,
            Double totalPrice,
            Boolean categoryOrPrice
    ) {
        List<Sku> result = new ArrayList<Sku>();
        for (Sku s : cartSkuList
        ) {
            if (
                    (categoryOrPrice && categoryEnum.equals(s.getSkuCategory()))
                            || (!categoryOrPrice && s.getTotalPrice() > totalPrice)
            ) {
                result.add(s);
            }
        }
        return result;
    }

根据不同的商品判断标准去过滤商品

实现方式:定义一个函数式接口,然后定义多个实现类,分别对应多个筛选条件.

函数式接口

有且只有一个抽象方法的接口被称为函数式接口 ,函数式接口适用于函数式编程的场景,Lambda就是Java中函数式编程的体现,可以使用Lambda表达式创建一个函数式接口的对象,一定要确保接口中有且只有一个抽象方法,这样Lambda才能顺利的进行推导。

java 复制代码
package lambda.cart;

/**
 * Sku选择谓词接口
 */
public interface SkuPredicate {
    /**
     * 选择判断标准
     * @param sku
     * @return
     */
    boolean test(Sku sku);
}

根据商品是否为图书分类进行筛选

java 复制代码
package lambda.cart;

/**
 * 该商品是否为图书分类
 */
public class SkuBooksCategoryPredicate implements SkuPredicate {
    @Override
    public boolean test(Sku sku) {
        return SkuCategoryEnum.BOOKS.equals(sku.getSkuCategory());
    }
}

根据商品的总价过滤商品

java 复制代码
package lambda.cart;

/**
 * 根据商品的总价过滤商品
 */
public class SkuTotalPricePredicate implements SkuPredicate {
    @Override
    public boolean test(Sku sku) {
        return sku.getTotalPrice() > 2000;
    }
}

需求实现

将函数式接口作为参数传给方法,然后调用函数式接口的test方法.接口有不同的实现类根据传递不同的实现类进行调用.

方法定义

java 复制代码
/**
     * Version: 4.0
     * 根据不同的商品判断标准
     *
     * @param cartSkuList  商品列表
     * @param skuPredicate 不同的商品属性判断标准
     * @return
     */
    public static List<Sku> filterSku(List<Sku> cartSkuList, SkuPredicate skuPredicate) {
        List<Sku> result = new ArrayList<Sku>();
        for (Sku s : cartSkuList
        ) {
            if (skuPredicate.test(s)) {
                result.add(s);
            }
        }
        return result;
    }

实体类的调用方法

java 复制代码
/**
     * 将判断逻辑参数化之实体类
     */
    @Test
    public void filterSku2() {
        List<Sku> cartSkuList = CartService.getCartSkuList();
        List<Sku> skus = CartService.filterSku(cartSkuList, new SkuBooksCategoryPredicate());
        System.out.println(JSON.toJSONString(skus, true));

    }

匿名类的调用方法

java 复制代码
/**
     * 将判断逻辑参数化之 匿名类
     */
    @Test
    public void filterSku3() {
        List<Sku> cartSkuList = CartService.getCartSkuList();
        List<Sku> skus = CartService.filterSku(cartSkuList, new SkuPredicate() {
            @Override
            public boolean test(Sku sku) {
                return sku.getSkuPrice() >= 1000;
            }
        });
        System.out.println(JSON.toJSONString(skus, true));

    }

Lambda方法进行调用

java 复制代码
/**
     * 将判断逻辑参数化之 Lambda
     */
    @Test
    public void filterSku4() {
        List<Sku> cartSkuList = CartService.getCartSkuList();
        List<Sku> skus = CartService.filterSku(cartSkuList, (Sku sku) -> sku.getSkuPrice() >= 1000);
        System.out.println(JSON.toJSONString(skus, true));

    }
相关推荐
hlsd#41 分钟前
go mod 依赖管理
开发语言·后端·golang
陈大爷(有低保)1 小时前
三层架构和MVC以及它们的融合
后端·mvc
亦世凡华、1 小时前
【启程Golang之旅】从零开始构建可扩展的微服务架构
开发语言·经验分享·后端·golang
河西石头1 小时前
一步一步从asp.net core mvc中访问asp.net core WebApi
后端·asp.net·mvc·.net core访问api·httpclient的使用
2401_857439691 小时前
SpringBoot框架在资产管理中的应用
java·spring boot·后端
怀旧6661 小时前
spring boot 项目配置https服务
java·spring boot·后端·学习·个人开发·1024程序员节
阿华的代码王国1 小时前
【SpringMVC】——Cookie和Session机制
java·后端·spring·cookie·session·会话
小码编匠2 小时前
领域驱动设计(DDD)要点及C#示例
后端·c#·领域驱动设计
德育处主任Pro2 小时前
『Django』APIView基于类的用法
后端·python·django
哎呦没4 小时前
SpringBoot框架下的资产管理自动化
java·spring boot·后端