本章节中,我们通过一个实战案例对比原始集合操作与Stream集合操作具体有哪些不同,直观地展示Stream集合操作对编程效率的提升。
针对上面的购物车,我们想要
@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方式下如何编码实现我们的需求:
@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编程,对于提升我们的编码效率以及提升代码可读性都有着明显的收益。
版权声明:
原创不易,洗文可耻。除非注明,本博文章均为原创,转载请以链接形式标明本文地址。