Java Stream技术问询:如何过滤OutOfStockItem后获取剩余Item列表及元素数量
解决方案:过滤OutOfStockItem并获取列表与总数量
我来帮你梳理下问题,你原来的代码有两个关键问题:
- 过滤条件搞反了:你用
filter(OutOfStockItem.class::isInstance)是在保留所有OutOfStockItem,但你实际需要的是过滤掉这些缺货商品,保留普通Item。 - 分组计数不是你要的总数量:
groupingBy(Function.identity(), Collectors.counting())会把每个不同的Item实例作为key单独计数,而你需要的是过滤后列表的总元素个数。
下面是几种可行的实现方案:
方案1:分步获取(最直观)
先收集过滤后的列表,再直接取列表的长度作为数量,代码清晰易懂:
// 过滤掉所有OutOfStockItem,保留普通Item List<Item> remainingItems = basket.getList().stream() .filter(item -> !(item instanceof OutOfStockItem)) // 如果你用的是Java 11+,可以用Predicate.not简化写法 // .filter(Predicate.not(OutOfStockItem.class::isInstance)) .collect(Collectors.toList()); // 获取剩余元素的总数量 long itemCount = remainingItems.size();
之后你就可以直接使用remainingItems(剩余Item列表)和itemCount(总数量)了。
方案2:一次性封装结果(适合需要返回复合结果的场景)
如果需要把两个结果封装成一个对象返回,可以自定义一个结果类,配合collectingAndThen一次性完成收集:
// 先定义一个用来封装结果的类(可以是你的业务类里的静态内部类) static class ItemFilterResult { private List<Item> items; private long count; public ItemFilterResult(List<Item> items, long count) { this.items = items; this.count = count; } // 按需添加getter方法 public List<Item> getItems() { return items; } public long getCount() { return count; } } // 一次性收集并封装结果 ItemFilterResult result = basket.getList().stream() .filter(Predicate.not(OutOfStockItem.class::isInstance)) .collect(Collectors.collectingAndThen( Collectors.toList(), filteredList -> new ItemFilterResult(filteredList, filteredList.size()) )); // 使用时直接调用getter即可 List<Item> items = result.getItems(); long count = result.getCount();
方案3:不收集列表直接统计数量(如果只需要数量,不需要列表)
如果你的场景只需要总数量,不需要保留列表,可以直接用count()方法:
long itemCount = basket.getList().stream() .filter(Predicate.not(OutOfStockItem.class::isInstance)) .count();
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

