0

I have a map of objects that look like this:

KEY[string]: id VALUE[object]: Stock

Stock object has a price attribute that is a BigDecimal.

I want to iterate through this map and find a) the sum b) max stock price.

I want to use Java 8 streams API to increase performance so I tried the following:

AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal(0));
myMap.forEach( (id, Stock) -> {
   sum.updateAndGet(v -> v.add(Stock.getPrice()));
})

Is this the correct way to total BigDecimal using forEach? And how can I do the same to find the max stock price in the map?

john
  • 1,561
  • 3
  • 20
  • 44
  • 2
    No! Use a `reduce` operation. This is definitely not the correct way. If you’re using advanced concurrency constructs to work around the effectively final requirement, you are definitely not doing things correctly! – Boris the Spider Aug 08 '18 at 06:30
  • If you don't care about loss of precision you could do `myMap.values().stream().map(String::getPrice).mapToDouble(BigDecimal::doubleValue).summaryStatistics()`. See [`DoubleSummaryStatistics`](https://docs.oracle.com/javase/8/docs/api/java/util/DoubleSummaryStatistics.html). – Boris the Spider Aug 08 '18 at 06:37
  • @BoristheSpider the existing question that you linked; does it use a reduce operation? – john Aug 08 '18 at 06:42
  • Because it uses a mutable container to collect the summary statistics - you asked for `sum` _and_ `max` - it uses a custom `Collector`. If you only wanted one or the other, a `reduce` would make sense because `BigDecimal` is immutable. – Boris the Spider Aug 08 '18 at 06:43
  • @BoristheSpider while List has a method named `stream` this is not available for Map. Any suggestion? (this is in relation to the question you linked) – john Aug 08 '18 at 07:33
  • Look at my example above. – Boris the Spider Aug 08 '18 at 07:34
  • Missed it, thanks! – john Aug 08 '18 at 07:35

0 Answers0