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

    }
相关推荐
王码码20355 小时前
Go语言的测试:从单元测试到集成测试
后端·golang·go·接口
王码码20355 小时前
Go语言中的测试:从单元测试到集成测试
后端·golang·go·接口
嵌入式×边缘AI:打怪升级日志6 小时前
使用JsonRPC实现前后台
前端·后端
小码哥_常7 小时前
从0到1:Spring Boot 中WebSocket实战揭秘,开启实时通信新时代
后端
lolo大魔王7 小时前
Go语言的异常处理
开发语言·后端·golang
IT_陈寒9 小时前
Python多进程共享变量那个坑,我差点没爬出来
前端·人工智能·后端
码事漫谈9 小时前
2026软考高级·系统架构设计师备考指南
后端
AI茶水间管理员10 小时前
如何让LLM稳定输出 JSON 格式结果?
前端·人工智能·后端
其实是白羊11 小时前
我用 Vibe Coding 搓了一个 IDEA 插件,复制URI 再也不用手动拼了
后端·intellij idea
用户83562907805111 小时前
Python 操作 Word 文档节与页面设置
后端·python