1

I have a class, MyClass, like this:

public class MyClass() {
  String name;
  Long amount;

  public MyClass() {
    // No arguments constructor
  }

  public Long getAmount() {
    return this.amount;
  }
}

If I want to get the sum of amount in an ArrayList of MyClass items, usually I would do this:

// assuming ArrayList<MyClass> myClassList
Long amount = 0L;
for (MyClass x : myClassList) {
  amount += x.getAmount();
}

But now to improve performance, I am trying to use Stream.reduce(). My approach:

// assuming ArrayList<MyClass> myClassList
// reduce all MyClass items to a single MyClass item that holds the total amount
Long amount = myClassList.stream().reduce(new MyClass(), 
(curr, next) -> {
  Long currAmount = curr.getAmount() != null ? curr.getAmount() : 0L;  // subtotal
  Long nextAmount = next.getAmount() != null ? next.getAmount() : 0L;  // next value to add
  curr.setAmount(currAmount + nextAmount);  // next subtotal
  return curr;
}).getAmount();

Is there a better way to do so? And how would the reduction be affected if currAmount or nextAmount is null?

samabcde
  • 6,988
  • 2
  • 25
  • 41
Zhe Sheng Lim
  • 154
  • 2
  • 14
  • 1
    Changing to a stream for this case is unlikely to improve performance. In that case it is better to just stick with the simpler and more readable variant with the for-each loop. – Mark Rotteveel Dec 23 '21 at 08:09

2 Answers2

2

But now to improve performance, I am trying to use Stream.reduce()

Stream does not improve performance, the main idea using stream is benefit from functional programming. If you want to improve performance, please do proper benchmarking. Anyway, you can simplify the stream as below.

Long amount = myClassList.stream()
                  .mapToLong(m -> m.getAmount() == null ? 0L : m.getAmount()).sum();
samabcde
  • 6,988
  • 2
  • 25
  • 41
1

You can also use reduce as like below:

Long amount = myClassList.stream()
            .filter(m -> m.getAmount() != null)
            .mapToLong(Product::getAmount)
            .reduce(0, Long::sum);
Sandeep Tiwari
  • 2,042
  • 3
  • 24
  • 47