如何优化Java Stream实现嵌套列表过滤后的字段求和逻辑?
优化Java Stream计算税率总和的方案
需求回顾
过滤掉itemClass为200的Item对象,计算剩余所有Tax对象的taxRate字段总和。
原代码问题分析
原代码存在两处逻辑错误,同时使用三次Stream并生成中间集合,冗余且低效:
- 数据初始化bug:创建
item2、item3时错误地给item1设置itemClass,导致所有Item的itemClass最终都是300;设置tax2、tax3税率时误用tax1的set方法,导致税率值错误。 - Stream冗余:生成了
filteredItemList、filteredTaxList两个中间集合,不仅占用额外内存,还多了两次集合遍历操作。
优化后的实现方案
直接通过单一Stream链式操作完成所有逻辑,避免中间集合开销,同时修正数据初始化错误:
public class Item { private long itemClass; private List<Tax> taxList; public long getItemClass() { return itemClass; } public void setItemClass(long itemClass) { this.itemClass = itemClass; } public List<Tax> getTaxes() { return taxList; } public void setTaxList(List<Tax> taxList) { this.taxList = taxList; } } public class Tax { private double taxRate; public double getTaxRate() { return taxRate; } public void setTaxRate(double taxRate) { this.taxRate = taxRate; } } public class App { public static void main(String[] args) { // 修正数据初始化错误 Item item1 = new Item(); item1.setItemClass(100); Item item2 = new Item(); item2.setItemClass(200); Item item3 = new Item(); item3.setItemClass(300); Tax tax1 = new Tax(); tax1.setTaxRate(0.01); Tax tax2 = new Tax(); tax2.setTaxRate(0.02); Tax tax3 = new Tax(); tax3.setTaxRate(0.03); item1.setTaxList(Arrays.asList(tax1, tax2)); item2.setTaxList(Arrays.asList(tax1, tax3)); item3.setTaxList(Arrays.asList(tax1, tax2, tax3)); List<Item> itemList = Arrays.asList(item1, item2, item3); // 单一Stream链完成过滤、展开、求和 double totalTaxRate = itemList.stream() .filter(item -> item.getItemClass() != 200) .flatMap(item -> item.getTaxes().stream()) .mapToDouble(Tax::getTaxRate) .sum(); System.out.println(totalTaxRate); // 输出预期结果0.09 } }
优化说明
- 减少中间开销:去掉了两个中间集合,避免不必要的内存分配和遍历操作
- 高效链式操作:数据仅遍历一次,依次完成过滤、展开Tax列表、转换为数值流、求和,逻辑连贯且性能更优
- 代码简洁性:使用方法引用
Tax::getTaxRate简化Lambda表达式,提升代码可读性
内容的提问来源于stack exchange,提问作者mihaw70362
相关产品推荐
相关产品推荐

