Ahmad Abdullah
Ahmad Abdullah

Reputation: 45

collecting the sum of a field in java stream

consider the following class:

public class PersonalExpense {
    private String name;
    private int currentExpenses;

    ...

how to can i write a java stream "pipeline" that works in the same way as the first method (getRemainingCompanyBalance). this code results in an error.

the list contains separate lists for each department. each entry in the sub-list is an instance of the class. name/cost:

de#1first"/9900, de#1second"/8700, de#2first"/8500, de#2second"/10000, de#3first"/7800, de#3second"/6900

    private static long getRemainingCompanyBalance ( long initialBalance, List<ArrayList<PersonalExpense>> total) {
        long remainingBalance = initialBalance;
        for (List<PersonalExpense> departmentExpense : total) {
            for (PersonalExpense personalExpense : departmentExpense) {
                System.out.println(personalExpense.getName());
                remainingBalance = remainingBalance - personalExpense.getCurrentExpenses();
            }
        }
        return remainingBalance;
    }

    public static long getRemainingCompanyBalanceLambda ( long initialBalance, List<ArrayList<PersonalExpense>> total) {
        long remainingBalance = initialBalance;


        Integer sum = total
        .stream()
        .flatMap(Collection::stream)
        .filter(pe -> pe instanceof PersonalExpense)
        .map (pe -> (PersonalExpense) pe)
        .collect(Collectors.toList())
        .mapToInt(PersonalExpense::getCurrentExpenses)
        .sum();


        return remainingBalance -= sum;
    }

}

i'm trying to collect costs, then subtract them from the balance

Upvotes: 0

Views: 514

Answers (3)

burak isik
burak isik

Reputation: 571

With mapToInt function

int sum = total.stream()
         .mapToInt(PersonalExpense::getCurrentExpenses)
         .sum();

With summingInt function

int sum = total.stream()
         .collect(Collectors.summingInt(PersonalExpense::getCurrentExpenses));

Upvotes: 0

Eugene
Eugene

Reputation: 120858

public static long getRemainingCompanyBalanceLambda ( long initialBalance, List<ArrayList<PersonalExpense>> total) {

   int sum = total.stream()
        .flatMap(List::stream)
        .mapToInt(PersonalExpense::getCurrentExpenses)
        .sum();

   return initialBalance - sum;

}

Upvotes: 1

Eran
Eran

Reputation: 393841

You got some unnecessary method calls. You don't need to filter the Stream, since it already contains just PersonalExpense instances, and you shouldn't collect it to a List, because that would prevent you from mapping it to an IntStream and computing the sum.

public static long getRemainingCompanyBalanceLambda ( long initialBalance, List<ArrayList<PersonalExpense>> total) {
    return initialBalance - total
    .stream()
    .flatMap(Collection::stream)
    .mapToInt(PersonalExpense::getCurrentExpenses)
    .sum();
}

Upvotes: 0

Related Questions