文章目录
  1. 1. 案例:对比原始集合操作与Stream集合操作
    1. 1.1. 需求场景:
    2. 1.2. 原始集合操作:
    3. 1.3. Stream集合操作:
  2. 2. 阶段小结

本章节中,我们通过一个实战案例对比原始集合操作与Stream集合操作具体有哪些不同,直观地展示Stream集合操作对编程效率的提升。

案例:对比原始集合操作与Stream集合操作

需求场景:

针对上面的购物车,我们想要

  1. 全局查看购物车中都有哪些商品
  2. 将购物车中的图书类商品进行过滤(删除图书类商品)
  3. 在其余商品中挑选两件最贵的
  4. 打印出上述两件商品的名称和总价

原始集合操作:

@Test
public void traditionalWay() {
    // 1. 打印所有商品
    List<Sku> skus = CartService.getCartSkuList();
    for (Sku sku : skus) {
        System.out.println(JSON.toJSONString(sku, true));
    }
    // 2. 过滤图书类商品
    List<Sku> notIncludeBooksList = new ArrayList<>();
    for (Sku sku : skus) {
        if (!sku.getSkuCategory().equals(SkuCategoryEnum.BOOKS)) {
            notIncludeBooksList.add(sku);
        }
    }
    // 3. 其余商品中挑选两件最贵的 价格倒排序,取top2
    // 3.1 先排序
    notIncludeBooksList.sort(new Comparator<Sku>() {
        @Override
        public int compare(Sku sku0, Sku sku1) {
            if (sku0.getTotalPrice() > sku1.getTotalPrice()) {
                return -1;
            }
            if (sku0.getTotalPrice() < sku1.getTotalPrice()) {
                return 1;
            }
            return 0;
        }
    });

    // 3.2 取top2
    List<Sku> top2SkuList = new ArrayList<>();
    for (int i = 0; i < 2; i++) {
        top2SkuList.add(notIncludeBooksList.get(i));
    }
    // 4. 打印出上述两件商品的名称和总价
    // 4.1 求两件商品总价
    double totalMoney = 0.0;
    for (Sku sku : top2SkuList) {
        totalMoney += sku.getTotalPrice();
    }
    // 4.2 获取两件商品名称
    List<String> resultSkuNameList = new ArrayList<>();
    for (Sku sku : top2SkuList) {
        resultSkuNameList.add(sku.getSkuName());
    }
    // 打印输出结果
    System.out.println("结果商品名称: " + JSON.toJSONString(resultSkuNameList, true));
    System.out.println("商品总价:" + totalMoney);
}

运行结果:

{"skuCategory":"ELECTRONICS","skuId":2,"skuName":"无人机","skuPrice":1000.0,"totalNum":10,"totalPrice":1000.0}
{"skuCategory":"ELECTRONICS","skuId":1,"skuName":"VR一体机","skuPrice":2100.0,"totalNum":10,"totalPrice":2100.0}
{"skuCategory":"CLOTHING","skuId":4,"skuName":"牛仔裤","skuPrice":60.0,"totalNum":10,"totalPrice":60.0}
{"skuCategory":"CLOTHING","skuId":13,"skuName":"衬衫","skuPrice":120.0,"totalNum":10,"totalPrice":120.0}
{"skuCategory":"BOOKS","skuId":121,"skuName":"Java编程思想","skuPrice":100.0,"totalNum":10,"totalPrice":100.0}
{"skuCategory":"BOOKS","skuId":3,"skuName":"程序化广告","skuPrice":80.0,"totalNum":10,"totalPrice":80.0}
结果商品名称: [
    "VR一体机",
    "无人机"
]
商品总价:3100.0

我们可以看到传统的集合操作还是写了比较多的代码,而且在编码过程中为了满足各种要求,我们通过声明新的容器来接受过程中的操作结果,这带来了内存使用量的增加。

接下来看一下Stream方式下如何编码实现我们的需求:

Stream集合操作:

@Test
public void streamWay() {
    AtomicReference<Double> money = new AtomicReference<>(Double.valueOf(0.0));
    List<String> resultSkuNameList = CartService.getCartSkuList()
                    // 获取集合流
            .stream()
            /**1. 打印商品信息*/
            .peek(sku -> System.out.println(JSON.toJSONString(sku)))
            /**2. 过滤掉所有的图书类商品*/
            .filter(sku -> !SkuCategoryEnum.BOOKS.equals(sku.getSkuCategory()))
            /**3. 价格进行排序,默认是从小到大,调用reversed进行翻转排序即从大到小*/
            .sorted(Comparator.comparing(Sku::getTotalPrice).reversed())
            /**4. 取top2*/
            .limit(2)
            /**累加金额*/
            .peek(sku -> money.set(money.get() + sku.getTotalPrice()))
            /**获取商品名称*/
            .map(sku -> sku.getSkuName())
            .collect(Collectors.toList());
    System.out.println("商品总价:" + money.get());
    System.out.println("商品名列表:" + JSON.toJSONString(resultSkuNameList));
}

运行结果:

{"skuCategory":"ELECTRONICS","skuId":2,"skuName":"无人机","skuPrice":1000.0,"totalNum":10,"totalPrice":1000.0}
{"skuCategory":"ELECTRONICS","skuId":1,"skuName":"VR一体机","skuPrice":2100.0,"totalNum":10,"totalPrice":2100.0}
{"skuCategory":"CLOTHING","skuId":4,"skuName":"牛仔裤","skuPrice":60.0,"totalNum":10,"totalPrice":60.0}
{"skuCategory":"CLOTHING","skuId":13,"skuName":"衬衫","skuPrice":120.0,"totalNum":10,"totalPrice":120.0}
{"skuCategory":"BOOKS","skuId":121,"skuName":"Java编程思想","skuPrice":100.0,"totalNum":10,"totalPrice":100.0}
{"skuCategory":"BOOKS","skuId":3,"skuName":"程序化广告","skuPrice":80.0,"totalNum":10,"totalPrice":80.0}
商品总价:3100.0
商品名列表:["VR一体机","无人机"]

我们可以看到,通过Stream集合操作,运行结果与传统集合操作完全一致。但是编码量却能够显著减少。

辩证的分析一下,如果对Stream操作没有一个较为明确的了解,阅读这段代码确实有些难度,但是只要有一点了解,Stream集合操作代码带来的无论是编码量显著降低还是可读性提升,亦或是内存空间的节约都是可观的。

阶段小结

可见,学习并运用Lambda及Stream编程,对于提升我们的编码效率以及提升代码可读性都有着明显的收益。



版权声明:

原创不易,洗文可耻。除非注明,本博文章均为原创,转载请以链接形式标明本文地址。

文章目录
  1. 1. 案例:对比原始集合操作与Stream集合操作
    1. 1.1. 需求场景:
    2. 1.2. 原始集合操作:
    3. 1.3. Stream集合操作:
  2. 2. 阶段小结
Fork me on GitHub