【问题标题】:Iterating through list and summing up all amounts where types are the same遍历列表并总结类型相同的所有金额
【发布时间】:2019-05-15 01:01:01
【问题描述】:

我需要将MonthlyExpenses 列表中类型相等的所有金额相加。

在我的代码中,我将expensesobligations 附加到MonthlyExpenses 的同一个列表中。

这是我的代码:

List<MonthlyExpenses> monthlyExpenses =  new ArrayList<MonthlyExpenses>();
List<Expenses> expenses = getExpenses(borrower);
List<Obligations> obligations = getObligations(borrower);

if(expenses!=null){
    monthlyExpenses.addAll(createMonthlyExpenses(expenses));
}
if(obligations!=null){
   monthlyExpenses.addAll(createMonthlyObligations(obligations));
}

...
public class MonthlyExpenses {

  private String type = null;
  private BigDecimal amount = null;

  public String getType() {
    return type;
  }

  public void setType(String type) {
    this.type = type;
  }

  public BigDecimal getAmount() {
    return amount;
  }

  public void setAmount(BigDecimal amount) {
    this.amount = amount;
  }
}

1st IF statement,如果执行返回:

class MonthlyExpenses{
    type: FOOD
    amount: 150.00
}, class MonthlyExpenses{
    type: UTILITIES
    amount: 250.00
}, class MonthlyExpenses{
    type: TRANSPORTATION
    amount: 350.00
}, class MonthlyExpenses{
    type: CHILD CARE
    amount: 450.00
}, class MonthlyExpenses{
    type: CREDIT CARDS
    amount: 878.00
}, class MonthlyExpenses{
    type: Other
    amount: 2888.64
}

2nd IF statement,如果执行返回:

class MonthlyExpenses{
    type: AUTO LOANS
    amount: 200.00
}, class MonthlyExpenses{
    type: CREDIT CARDS
    amount: 300.00
}, class MonthlyExpenses{
    type: INSTALLMENT LOANS
    amount: 50.00
}, class MonthlyExpenses{
    type: ALIMONY/SUPPORT
    amount: 75.00
}, class MonthlyExpenses{
    type: Other
    amount: 10096.87
}

如果类型相等,我如何签入List&lt;MonthlyExpenses&gt; 并将这些金额相加并返回该新列表?

【问题讨论】:

  • 您能分享一下您的 BorrowerFinancialMonthlyExpenses 课程是什么样的吗?

标签: java algorithm design-patterns collections java-8


【解决方案1】:

您可以通过使用streamscollectors 来实现:

    private static List<MonthlyExpense> createMonthlyExpenses(List<MonthlyExpense> expenses) {
        Map<String, Double> sums = expenses.stream()
                .collect(Collectors.groupingBy(
                            MonthlyExpense::getType, 
                            Collectors.summingDouble(MonthlyExpense::getAmount))
        );
        return sums.entrySet().stream()
                .map(entry -> new MonthlyExpense(entry.getKey(), entry.getValue()))
                .sorted(Comparator.comparing(MonthlyExpense::getType))
                .collect(Collectors.toList());
    }

这项工作的方式是使用collect 将所有费用按(groupBy)他们的type 分组并用作求和 下游收集器。然后,您使用此映射(在类型和总金额之间)创建具有您需要的总费用的对象。以下课程是一个完整的实际应用程序,供您使用:

import java.util.*;
import java.util.stream.Collectors;

public class FinancialCalculator {

    static class MonthlyExpense {
        private String type;
        private double amount;

        public MonthlyExpense(String type, double amount) {
            this.type = type;
            this.amount = amount;
        }

        public String getType() { return type; }
        public double getAmount() { return amount; }
        public String toString() { return String.format("%s: %.2f", type, amount); }
    }

    private static List<MonthlyExpense> createMonthlyExpenses(List<MonthlyExpense> expenses) {
        Map<String, Double> sums = expenses.stream()
                .collect(Collectors.groupingBy(
                            MonthlyExpense::getType, 
                            Collectors.summingDouble(MonthlyExpense::getAmount))
        );
        return sums.entrySet().stream()
                .map(entry -> new MonthlyExpense(entry.getKey(), entry.getValue()))
                .collect(Collectors.toList());
    }

    public static void main(String[] args) {
        MonthlyExpense[] expenses = new MonthlyExpense[] {
                new MonthlyExpense("UTILITIES", 75),
                new MonthlyExpense("CREDIT", 1000),
                new MonthlyExpense("UTILITIES", 50),
                new MonthlyExpense("CREDIT", 2000),
                new MonthlyExpense("UTILITIES", 150),
                new MonthlyExpense("CAR", 344)
        };  
        System.out.println(createMonthlyExpenses(Arrays.asList(expenses)));
    }
}

Complete code on GitHub

希望这会有所帮助。

【讨论】:

  • @marco-r 我的自动生成的 BorrowerFinancialMonthlyExpenses 类没有这两个元素的构造函数。即:我不能这样做:.map(entry -> new MonthlyExpense(entry.getKey(), entry.getValue()))。我还有其他方法可以映射我的“总和”吗?我可以只创建 BorrowerFinancialMonthlyExpenses borrowerFinancials = new BorrowerFinancialMonthlyExpenses();设置在这里并返回?
  • 是的,你可以这样做。只需创建一个方法来执行此操作(Expense createExpense(...)),并替换条目的映射以使用此方法而不是答案中使用的构造函数:map(entry -&gt; createExpense(entry.getKey(), entry.getValue()))
  • @marco-r 我在做 sums.entrySet().stream().map(entry -> ... 时也可以按字母顺序对它们进行排序吗?
  • 是的,您可以,只需添加我在映射条目后添加到答案中的额外行:.sorted(Comparator.comparing(MonthlyExpense::getType))
  • 我是这样做的:.sorted(Map.Entry.comparingByKey())
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多