Java中比较同一对象多组取值及筛选最优场景的最佳实现方案
嘿,我来帮你优化这个方案——你现在的问题核心是用了太多Map来存每个场景的数据,不仅费内存,后续对比也麻烦。咱们换个更高效的思路,把场景参数和对应的计算结果绑定在一起,要么实时跟踪最优场景,要么把所有场景结果封装成对象统一管理,完全没必要搞一堆零散的Map。
第一步:封装场景结果,替代零散的Map
首先,咱们创建一个专门的类来存储单个场景的关键信息,比如场景的核心参数(比如你的补贴值)、该场景下的总指标(比如所有员工成本的总和),如果需要保留每个员工的明细数据,也可以在这个类里加对应的存储结构。
// 封装单个场景的计算结果 class ScenarioResult { // 场景的核心参数(比如当前补贴值) private double allowance; // 该场景下所有员工成本的总和(用来判断最优的核心指标) private double totalCostSum; // 可选:如果需要保留每个员工的明细数据,就加这个Map private Map<Employee, List<Double>> employeeCostDetails; // 构造器(根据需求选不同的构造方式) // 只需要核心参数和总和的构造器 public ScenarioResult(double allowance, double totalCostSum) { this.allowance = allowance; this.totalCostSum = totalCostSum; } // 需要保留明细的构造器 public ScenarioResult(double allowance, double totalCostSum, Map<Employee, List<Double>> employeeCostDetails) { this.allowance = allowance; this.totalCostSum = totalCostSum; this.employeeCostDetails = employeeCostDetails; } // Getter方法,供后续筛选使用 public double getAllowance() { return allowance; } public double getTotalCostSum() { return totalCostSum; } public Map<Employee, List<Double>> getEmployeeCostDetails() { return employeeCostDetails; } }
第二步:优化主逻辑,避免创建多个Map
接下来修改你的主方法逻辑,不用为每个场景创建新的Map,而是在循环计算每个场景时,直接计算总指标,并把场景信息封装到ScenarioResult中。这里分两种情况:
情况1:只需要找最优场景,不需要保留所有场景的明细
这种情况下,甚至不用存储所有场景的结果,只需要在循环中实时更新当前最优的场景即可,内存占用极低:
public class App { public static void main(String[] args) { Set<Employee> employees = ...; // 你的员工集合 double minAllowance = 10; double maxAllowance = 30; double stepSize = 5; ScenarioResult bestScenario = null; while (minAllowance <= maxAllowance) { double currentAllowance = minAllowance; double totalSum = 0.0; // 计算当前补贴下所有员工的成本总和 for (Employee e : employees) { List<Double> newCostList = calculateAdjustedCosts(e, currentAllowance); // 累加该员工的成本到场景总总和 totalSum += newCostList.stream().mapToDouble(Double::doubleValue).sum(); } // 实时更新最优场景 ScenarioResult currentResult = new ScenarioResult(currentAllowance, totalSum); if (bestScenario == null || currentResult.getTotalCostSum() > bestScenario.getTotalCostSum()) { bestScenario = currentResult; } minAllowance += stepSize; } // 输出最优结果 assert bestScenario != null; System.out.println("最优补贴值: " + bestScenario.getAllowance()); System.out.println("对应的总成本总和: " + bestScenario.getTotalCostSum()); } // 抽离计算单个员工调整后成本的方法,让代码更清晰 private static List<Double> calculateAdjustedCosts(Employee employee, double allowance) { double[] originalSalary = employee.getWeeklySalary(); double[] originalCost = employee.getWeeklyCost(); List<Double> adjustedCosts = new ArrayList<>(); // 这里替换成你实际的成本计算逻辑 for (int i = 0; i < originalCost.length; i++) { // 示例:成本 = 原成本 + 补贴比例*周薪资 double newCost = originalCost[i] + (allowance / 100) * originalSalary[i]; adjustedCosts.add(newCost); } return adjustedCosts; } }
情况2:需要保留所有场景的明细,方便后续分析
如果需要复盘每个场景的具体数据,就把所有ScenarioResult存入一个列表,最后再筛选最优:
public class App { public static void main(String[] args) { Set<Employee> employees = ...; // 你的员工集合 double minAllowance = 10; double maxAllowance = 30; double stepSize = 5; List<ScenarioResult> allScenarioResults = new ArrayList<>(); while (minAllowance <= maxAllowance) { double currentAllowance = minAllowance; double totalSum = 0.0; Map<Employee, List<Double>> currentEmployeeDetails = new HashMap<>(); for (Employee e : employees) { List<Double> newCostList = calculateAdjustedCosts(e, currentAllowance); currentEmployeeDetails.put(e, newCostList); totalSum += newCostList.stream().mapToDouble(Double::doubleValue).sum(); } // 把当前场景的完整数据存入列表 allScenarioResults.add(new ScenarioResult(currentAllowance, totalSum, currentEmployeeDetails)); minAllowance += stepSize; } // 用Stream筛选出总和最高的最优场景 ScenarioResult bestScenario = allScenarioResults.stream() .max(Comparator.comparingDouble(ScenarioResult::getTotalCostSum)) .orElseThrow(() -> new IllegalArgumentException("没有可评估的场景")); // 输出最优结果 System.out.println("最优补贴值: " + bestScenario.getAllowance()); System.out.println("对应的总成本总和: " + bestScenario.getTotalCostSum()); // 如果需要查看明细 bestScenario.getEmployeeCostDetails().forEach((emp, costs) -> System.out.println("员工" + emp.getEmployeeId() + "的周成本: " + costs) ); } // 同样的计算方法,省略重复代码 private static List<Double> calculateAdjustedCosts(Employee employee, double allowance) { // ... 逻辑同上 } }
为什么这个方案更好?
- 内存高效:不用为每个场景创建独立的Map,要么只存当前最优场景,要么把所有场景数据封装成对象统一管理,避免零散Map带来的内存浪费。
- 代码清晰:把场景参数、计算结果、明细数据封装在一起,逻辑一目了然,后续修改场景参数或计算逻辑都很方便。
- 筛选简单:用Java Stream的
max方法一行就能找到最优场景,比遍历一堆Map要高效得多。
内容的提问来源于stack exchange,提问作者5122014009
相关产品推荐
相关产品推荐

